描述:
《MFC程序员的WTL教程》里面第一章给了这个例子:
#include <iostream>
using namespace std;
template <class T>
class B1
{
public:
void SayHi()
{
T* pT = static_cast<T*>(this); // HUH?? 我将在下面解释
pT->PrintClassName();
}
protected:
void PrintClassName() { cout << "This is B1" << endl; }
};
class D1 : public B1<D1>
{
// No overridden functions at all
};
class D2 : public B1<D2>
{
protected:
void PrintClassName() { cout << "This is D2" << endl; }
};
int main(int, char *[])
{
D1 d1;
D2 d2;
d1.SayHi(); // prints "This is B1"
d2.SayHi(); // prints "This is D2"
//d1.PrintClassName();
//d2.PrintClassName();
getchar();
return 0;
}
我编译就有错。
1>e:\test\hert\hert\main.cpp(12) : error C2248: “D2::PrintClassName”: 无法访问 protected 成员(在“D2”类中声明)
1> e:\test\hert\hert\main.cpp(26) : 参见“D2::PrintClassName”的声明
1> e:\test\hert\hert\main.cpp(23) : 参见“D2”的声明
1> e:\test\hert\hert\main.cpp(9): 编译类 模板 成员函数“void B1<T>::SayHi(void)”时
我把PrintClassName改为public之后就好了
这是怎么回事?
按理说,protected应该也可以呀
但为啥这样会有错误?
还有一个问题呀,我不知道用这种递归模板有什么优势?
直接用d1.PrintClassName()和d2.PrintClassName()不是也可以吗?
也能达到相同的效果呀,不太明白
谢谢!!!
解决方案1:
基础问题:父类调用子类没法按照继承关系来处理,在编译器看来,它们就是两个相互独立的类/对象,所以是不可以访问“其它”类的保护成员的。
反过来,子类调用父类的,则适用继承关系。
你这里的干扰点是:以为模板可以把这种继承关系传递给父类。其实不然,模板只是节约了我们的代码量,可不负责把继承关系到处传递。
编译期多态
解决方案3:通过递归模板可实现多态.
解决方案4:按你这代码,当然得public了
您可能想查找下面的文章:
- 看了一下WTL,对这个代码看不懂
- 要用atl写个控件,涉及到界面的,怎么将wtl和atl结合起来用呐?用wtl来做控件的界面
- 在ATL中使用WTL中的CFileDialog实现预览功能出现的不刷新问题,高手进
- 使用WTL库,编译提示“cannotopenincludefile"atlresh"”,这是怎么回事?
- WTL能否用于ATL做COM组件的界面?需要注意什么?
- WTL中,怎么改变lineto画线的颜色和粗细?
- WTL问题,MainFrame加一个Destory响应怎么会这样
- 请大家帮忙看看这个:关于wtl
- WTL,CCodePageCombo继承CComboBoxT<ATL::CWindow>类,需要响应下拉菜单CloseUp的消息
- WTL下如何添加Mediaplayer控件