当前位置:网站首页 >> 旅游

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

时间:2020-01-17 02:08:23 来源:互联网 阅读:0次

在模板的帮助下,我们可以实现与之相同的行为。

程序50.

#include <iostream>

using namespace std;

template <typename T>

class Base {

public:

void fun() {

cout << "Base::fun" << endl;

}

void doSomething() {

T* pT = static_cast<T*>(this);

pT->fun();

}

};

class Drive : public Base<Drive> {

public:

void fun() {

cout << "Drive::fun" << endl;

}

};

int main() {

Drive obj;

obj.doSomething();

return 0;

}

程序的输出和前一个是一样的,所以我们可以用模板来模拟虚函数的行为。

程序中一个有趣的地方为:

class Drive : public Base<Drive> {

这表明我们可以将Drive类作为一个模板参数来传递。程序中另外一个有趣的地方是基类中的doSomething函数。

T* pT = static_cast<T*>(this);

pT->fun();

在这里基类的指针被转换为派生类的指针,因为派生类是作为Base类的模板参数传递的。这个函数可以通过指针来执行,由于指针指向了派生类的对象,所以派生类的对象就被调用了。

但是这就有一个问题了:我们为什么要这样做?答案是:这样可以节省虚函数带有的额外开销,也就是虚函数表指针、虚函数表以及节省了调用虚函数所花费的额外时间。这就是ATL中使组件尽可能小、尽可能快的主要思想。

现在,你的脑海中可能会浮现另外一个问题。如果依靠这一开销更少的技术可以模拟虚函数的话,那我们为什么还要调用虚函数呢?我们不应该用这一技术替换所有的虚函数吗?对于这一问题,我可以简短地回答你:不,我们不能用这一技术替换虚函数。

其实这一技术还存在一些问题。第一,你不能从Drive类进行更深层的继承,如果你试着这么做,那么它将不再会是虚函数的行为了。而对于虚函数来说,这一切就不会发生。一旦你将函数声明为虚函数,那么在派生类中的所有函数都会成为虚函数,无论继承链有多深。现在我们看看当从Drive中再继承一个类的时候会发生什么。

程序51.

#include <iostream>

using namespace std;

template <typename T>

class Base {

public:

void fun() {

cout << "Base::fun" << endl;

}

void doSomething() {

T* pT = static_cast<T*>(this);

pT->fun();

}

};

class Drive : public Base<Drive> {

public:

void fun() {

cout << "Drive::fun" << endl;

}

};

class MostDrive : public Drive {

public:

void fun() {

cout << "MostDrive::fun" << endl;

}

};

int main() {

MostDrive obj;

obj.doSomething();

return 0;

}

程序的输出和前一个一样。但是对于虚函数的情况来说,输出就应该是: MostDrive::fun

这一技术还有另外一个问题,就是当我们使用Base类的指针来存储派生类的地址的时候。

程序52.

#include <iostream>

using namespace std;

template <typename T>

class Base {

public:

void fun() {

cout << "Base::fun" << endl;

}

void doSomething() {

T* pT = static_cast<T*>(this);

pT->fun();

}

};

class Drive : public Base<Drive> {

public:

void fun() {

cout << "Drive::fun" << endl;

}

};

int main() {

Base* pBase = NULL;

pBase = new Drive;

return 0;

}

这个程序会给出一个错误,因为我们没有向基类传递模板参数。现在我们稍微修改一下,并传递模板参数。查看本文来源

剖宫产术后长期便秘吃什么
儿童止咳药不含防腐剂好吗
治ED哪种药36小时长效
腰疼引起的症状有哪些

相关文章

一周热门

热点排行

热门精选

友情链接:
媒体合作:

Copyright (c) 2011 八零CMS 版权所有 备案号:苏ICP备17012668号-3

网站地图