MFC程序员的WTL指南的第一个例子解释

#include "stdafx.h"

#include "iostream.h"

template <class T>
class B1
{
public: 
    void SayHi() 
    {
        T* pT = static_cast<T*>(this);   // HUH?? 我将在下面解释
 
        pT->PrintClassName();
    }
protected:
    void PrintClassName() { cout<<"This is B1"; }
};
 
class D1 : public B1<D1>
{
    // No overridden functions at all
};
 
class D2 : public B1<D2>
{
protected:
    void PrintClassName() { cout<<"This is D2"; }
};
 
int main(int argc, char* argv[])
{
    D1 d1;
    D2 d2;
 
    d1.SayHi();    // prints "This is B1"
    d2.SayHi();    // prints "This is D2"
	return 0;
}

 但是这个编译不通过,提示如下:
: error C2248: 'D2::PrintClassName' : cannot access protected member declared in class 'D2'

 

网上找的这个解释如下:

基础问题:父类调用子类没法按照继承关系来处理,在编译器看来,它们就是两个相互独立的类/对象,所以是不可以访问“其它”类的保护成员的。
反过来,子类调用父类的,则适用继承关系。

这里的干扰点是:以为模板可以把这种继承关系传递给父类。其实不然,模板只是节约了我们的代码量,可不负责把继承关系到处传递。

 

 其实这个错误,注是访问权限的问题,类中的成员函数,可以访问类中的其他成员函数

例1:

class B1
{
public: 
    void SayHi() 
    {
         PrintClassName();
    }
protected:
    void PrintClassName() { cout<<"This is B1"; }
};

 

 例2

class B1
{
public: 
    void SayHi() 
    {
         this->PrintClassName();
    }
protected:
    void PrintClassName() { cout<<"This is B1"; }
};

 

例3

 

class B1
{
public: 
    void SayHi() 
    {
		this->B1::PrintClassName();
    }
protected:
    void PrintClassName() { cout<<"This is B1"; }
};

 

例1,例2,例3是一样的,类中的SayHi()要访问到类中的PrintClassName() 函数,是通过this来访问的,要求this能够访问到B1::PrintClassName()函数,也就是说类中的SayHi()要访问到类中的PrintClassName() 函数,this指针并不是唯一的途径,只要这个指针(例如pT)能够访问到B1::PrintClassName()函数就行了,就是这个指针(例如pT)能够可见到B1::PrintClassName()函数.

   d1.SayHi();  是的形式是这样的pT->PrintClassName();相当于(D1的指针)->B1::PrintClassName();D1的指针能够访问得到B1::PrintClassName();所以编译会通过

 

d2.SayHi(); 是的形式是这样的pT->PrintClassName();相当于(D2的指针)->D2::PrintClassName();

而D2与B1是两个不同的类,在B1类中 当然不能访问到D2是的保护成员函数了,所以报错了.

 

 

 

这个例子,是编译时多态的例子.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值