关于派生类到基类的可访问性。。。

反方向 发布于 2012/10/27 18:23
阅读 875
收藏 0

以下是C++ primer 4 上说的:

1.如果是 public 继承,则用户代码和后代类都可以使用派生类到基类的转换。

2.如果类是使用 private 或 protected 继承派生的,则用户代码不能将派生类型对象转换为基类对象。

3.如果是 private 继承,则从 private 继承类派生的类不能转换为基类。

4.如果是 protected 继承,则后续派生类的成员可以转换为基类类型。

无论是什么派生访问标号,派生类本身都可以访问基类的 public 成员,因此,派生类本身的成员和友元总是可以访问派生类到基类的转换。
加载中
1
魔方帅帅
魔方帅帅

楼主作为初学者,知道太多啦~

@billzheng ,我回了啦!

魔方帅帅
魔方帅帅
回复 @billzheng : 公司的事情,连续忙了10天。私人也有些喜事,哈哈,私信分享。
billzheng
billzheng
最近忙什么去了?
0
billzheng
billzheng
你的问题是?
反方向
反方向
全是问题,我读了5、6遍这几句话了,可是不理解,能不能帮我解释下每一句。。(你读完难道就明白它说的是什么意思吗)
0
billzheng
billzheng

1. 只有是public 继承,如 class Derived : public Base. Base *p = new Derived();才允许转换. 因为非public继承,父类的public成员函数都非public了,你自然不能访问了. private继承的另外一个含义是'has a' 而不再是'is a'关系了。

2. 同上

3. 同上

4.我不相信通过Protected的子类能够转换为base类型。class Derived : protected Base... Base *p = new Derived(); 

.无论哪种派生,最严格的是private了;基类的public 成员成为派生类的Private,派生类当然能够访问自己private权限的成员了。

0
反方向
反方向

要不先说下第4句吧,那个在什么情况下后续派生类的成员可以转换为基类类型呀。我试了,不能转换呀,编译报错。

class Base{
public:
	void hi(){};
protected:
	int m;
};

class Derived : protected Base{
public:
	Derived(){}
	void f(){m = 3;}
};

class Son: public Derived{
	
};

int main()
{
	Base b;        //基类Base的对象
	Derived d;     //基类Base的派生类对象
	Son s;		   //基类Derived的派生类对象

	b = s;		   //error! 这也不能转换呀?
}

反方向
反方向
下面是我理解的,你看对不对。。。
反方向
反方向
我好像有点清楚了,再让我好好想一下。。。
billzheng
billzheng
Base *ps = new Son; 不可以
billzheng
billzheng
Derived *ps = new Son; 这样可以
billzheng
billzheng
书上说的转,是通过指针转。我对于第四点的描述是,不能转。
0
反方向
反方向
1.如果是 public 继承,则 用户代码后代类都可以使用派生类到基类的转换。

2.如果类是使用 private 或 protected 继承派生的,则 用户代码不能将派生类型对象转换为基类对象。

3.如果是 private 继承,则从 private 继承类派生的类不能转换为基类。
注: 由于第二代派生类是private派生,所以从第二代派生类往下派生的类将不再可访问基类中的成员,所以无法转换。

4.如果是 protected 继承,则后续派生类的成员可以转换为基类类型。 
注:由于第二代派生类是protected派生,所以从第二代派生类往下派生的类可以访问基类中的成员,所以可以转换。

无论是什么派生访问标号,派生类本身都可以访问基类的 public 成员,因此,派生类本身的成员和友元总是可以访问派生类到基类的转换。
注:第二代派生类当然可以访问从基类继承下来的成员(基类中的标号为public或protected),所以可以转换。

总结:只要知道访问的权限自然就知道可不可以转换了,
          对象的转换是用复制构造函数或赋值操作符进行的,
          这两个函数的参数类型是是const基类型的引用,
          在函数体中要访问派生类的成员,
          所以涉及到访问权限,近而涉及到可不可以转换。
0
billzheng
billzheng

在函数体中要访问派生类的成员,所以涉及到访问权限,近而涉及到可不可以转换

Son(const Son&)
Son& operator=(const Son&)

比如上面的copy构造函数和赋值构造函数传递的是引用。 传入的数据类型是未知的,你可以传入Base,Derived,Son等各种类型,这个时候要进行转换是要知道具体类型的,那就是通过多态(只有指针和引用才能支持多态)。如果是传入的参数(如Son)是通过protected/private继承,则无法转换,因为cast失败,所以你不能拷贝对象。

返回顶部
顶部