科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件ATL布幔下的秘密之模板技术

ATL布幔下的秘密之模板技术

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

如果你是个模板的高手,你就可以将ATL的学习作为一种享受。在这一节中,我将要尝试解释一些ATL使用的模板技术.

作者:李马编译 来源:VCKBASE 2007年10月19日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
代理设计模式也可以使用模板实现,智能指针就是一个例子。下面就是一个没有使用模板的简单版本智能指针。

  程序46.

#include <iostream>
using namespace std;

class Inner {
public:
void Fun() {
cout << "Inner::Fun" << endl;
}
};

class Outer {
private:
Inner* m_pInner;

public:
Outer(Inner* p_pInner) : m_pInner(p_pInner) {
}

Inner* operator -> () {
return m_pInner;
}
};

int main() {
Inner objInner;
Outer objOuter(&objInner);

objOuter->Fun();

return 0;
}

  程序的输出为:Inner::Fun()

  简单地说来,我们仅仅重载了->运算符,但是在实际的智能指针中,所有必须的运算符(例如=、==、!、&、*)都需要被重载。以上的智能指针有一个大问题:它只能包含指向Inner对象的指针。我们可以编写Outer类模板来取消这一限制,现在让我们来略微修改一下程序。

  程序47.

#include <iostream>
using namespace std;

class Inner {
public:
void Fun() {
cout << "Inner::Fun" << endl;
}
};

template <typename T>
class Outer {
private:
T* m_pInner;

public:
Outer(T* p_pInner) : m_pInner(p_pInner) {
}

T* operator -> () {
return m_pInner;
}
};

int main() {
Inner objInner;
Outer<Inner> objOuter(&objInner);

objOuter->Fun();

return 0;
}

  程序的输出和前一个一样,但是现在Outer类就可以包含任何类型了,只需要把类型作为模板参数传递进来即可。

  ATL中有两个智能指针,CComPtr和CComQIPtr。

  你可以用模板做一些有趣的事情,例如你的类可以在不同的情况下成为不同基类的子类。

  程序48.

#include <iostream>
using namespace std;

class Base1 {
public:
Base1() {
cout << "Base1::Base1" << endl;
}
};

class Base2 {
public:
Base2() {
cout << "Base2::Base2" << endl;
}
};

template <typename T>
class Drive : public T {
public:
Drive() {
cout << "Drive::Drive" << endl;
}
};

int main() {

Drive<Base1> obj1;
Drive<Base2> obj2;
return 0;
}

  程序的输出为:

Base1::Base1
Drive::Drive
Base2::Base2
Drive::Drive

  在这里,Drive类是继承自Base1还是Base2是由在对象创建的时候传递给模板的参数决定的。

  ATL也使用了这一技术。当你使用ATL创建COM组件的时候,CComObject就会继承自你的类。在这里ATL利用了模板,因为它不会预先知道你用来作COM组件而创建的类的名称。CComObject类定义于ATLCOM.H文件之中。

  在模板的帮助下,我们也可以模拟虚函数。现在让我们重新回忆一下虚函数,下面是一个简单的例子。

  程序49.

#include <iostream>
using namespace std;

class Base {
public:
virtual void fun() {
cout << "Base::fun" << endl;
}

void doSomething() {
fun();
}
};

class Drive : public Base {
public:
void fun() {
cout << "Drive::fun" << endl;
}
};

int main() {
Drive obj;
obj.doSomething();

return 0;
}

  程序的输出为:Drive::fun
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章