派生类向基类转换的可访问性

时间:2022-11-09 20:02:06

感觉基类、派生类的关系是很微妙的,派生类向基类转换的可访问性,C++ Primer(中文5版,Ch15.5)给出了三句解释说明:

  • 只有当Derived公有继承Base时,用户代码才能使用派生类向基类的转换;如果Derived继承Base是protected或private,则用户代码不能使用该转换。
  • 不论Derived以什么方式继承Base,Derived的成员函数和友元都能使用派生类向基类的转换;派生类对于其直接基类的类型转换对于派生类的成员和友元来说永远是可访问的。
  • 如果Derived继承Base的方式是public或protected,则Derived的派生类的成员和友元可以使用Derived向Base的类型转换;反之,如果Derived继承Base的方式是private,则不能使用。

下面说明之:
第一句话,这句话应该好懂。第一句话的意思用代码写出来如下所示:

class Base
{

// code segment...
};

class D1 : public Base
{

// code segment...
};

class D2 : protected Base
{

// code segment...
};

class D3 : private Base
{

// code segment...
};

int main()
{
D1 d1 = new D1();
D2 d2 = new D2();
D3 d3 = new D3();

Base B1 = d1; // publiuc继承,正确
Base B2 = d2; // protected继承,错误
Base B3 = d3; // privat继承,错误
}

第二句话的意思写成代码如下所示:

class Base
{
public:
fun();
// others...
};

class Derived : public Base
{
public:
friend void UseBaseFun(Base b);
void TestFun(Base b);
}

void UseBaseFun(Base b)
{
b.fun();
}

void Derived::TestFun(Base b)
{
b.fun();
}

int main()
{
Derived d1 = new Derived();
Derived d2 = new Derived();
// 参数是派生类向基类的转换,正确
d2.UseBaseFun(d1);
d2.TestBase(d1);

retunr 0;
}

第三句话翻译成代码如下所示,需要加以说明的是,subDerived继承Derived的方式不影响:

class Base
{
public:
fun();
// others...
};

class Derived : public/protected/private Base
{
};

class subDerived : public Derived
{
public:
void Test3rdSen(Base b);
};

void Test3rdSen(Base b)
{
b.fun();
};

int main()
{
Derived d = new Derived();
subDerived sd = new subDerived();

/* 如果subDerived继承Derived的方式是public或protected下面这句
话正确,如果继承方式是private,则下面这句话是错误的 */

sd.Test3rdSen(d);
}

以上三句话的理解全是个人理解,若有异议,可以留言或私信