注册 登录
编程论坛 C++教室

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

韩海0312 发布于 2017-05-22 21:11, 3388 次点击
C++ primer第五版有这样的描述和我实际编码的例子有点冲突,求教

c++ primer(第五版)描述:
假定D继承z自B:
1. 如果当D共有继承B时, 用户代码才能使用派生类向基类的转换; 如果D继承B的方式是受保护的或者私有的
则用户代码不能使用此转换。(这一点没有什么问题,关键是接下来两点和提示)

2.不论D以什么方式继承B,D的成员函数和友员都能使用派生类向基类的的转换,派生类向其直接基类的转换对
其成员和友员来说是永远可访问的。

3. 无论D继承B的方式是共有的或者保护的,则D的派生类的成员和友员可以使用D向B的类型转换; 反之, 如果
如果D继承B的方式是私有的,则不能使用。

tip. 对于代码中的给定节点来说,如果基类的共有成员是可访问的,则派生类向基类的转化是可访问的,反之则不行



我的代码特别简单,就是想试试友员

class Base {
public:
    virtual int get_prot() {return prot;}
protected:
    int prot = 3;
};

class Prot_derived : protected Base {
friend void func(Base *b);
public:
    virtual int get_prot() {return prot;}
};

void func(Base *b)
{
}

int main()
{
    Prot_derived pd;
    func(&pd); // error: ‘Base’ is an inaccessible base of ‘Prot_derived’
    // 针对c++ primer的描述第二条,这个友员为什么不能转换呢?
}

首先这个代码有点怪,
1. func不是基类的友员,所以不可以访问基类的保护成员和私有成员,但是在func应该可以访问基类的共有成员(tip)
2. func是派生类的友员,可是转换不允许, 到底哪里出错,我没有找到, (描述第二点)


在此多谢大家帮忙


[此贴子已经被作者于2017-5-22 22:03编辑过]

12 回复
#2
韩海03122017-05-22 21:13
在线等,挺急得
#3
rjsp2017-05-22 21:54
func(pd);
我怀疑你想写的是
func(&pd);
#4
韩海03122017-05-22 22:02
回复 3楼 rjsp
哦哦,是&fd, 因为刚开始写的是引用类型,改成的指针,

error 提示
error: ‘Base’ is an inaccessible base of ‘Prot_derived’
#5
rjsp2017-05-22 22:26
回复 4楼 韩海0312
还有疑问吗?
(不太明白你的代码意图,但看起来main应该成为友元才行)
#6
韩海03122017-05-22 22:54
回复 5楼 rjsp
其实我的意图挺简单,c++ primer描述说, 不管什么继承方式,基类的友员和成员函数可以进行
派生类到基类的转换, 但是我的这个例子里面不知到哪里除了问题
#7
韩海03122017-05-22 23:00
回复 6楼 韩海0312
派生类的友员和成员函数可以进行派生类到基类的转换
#8
rjsp2017-05-22 23:28
回复 6楼 韩海0312
可是发生转换的地方明明在main函数中呀
按你的意思,应该改
friend void func(Base *b);

friend int main( void );
#9
韩海03122017-05-23 14:08
回复 8楼 rjsp
恩,我尝试了你的说法一下是可以的,确实, 原先的写法,转换确实发生在main里 而不是发生在func里

但是还有一点没有搞清楚, 就是c++primer tip的描述
tip. 对于代码中的给定节点来说,如果基类的共有成员是可访问的,则派生类向基类的转化是可访问的,反之则不行

如这条描述, 那么在main 中, func(&pd) 这里pd确实访问不到基类的共有成员,因为protected 继承,但是即使是public继承
也是访问不到基类的共有成员(只能访问到基类内嵌到派生类的共有成员),那tip是不是应该该一下才对呢

tip. 对于代码中的给定节点来说,如果基类内嵌到派生类的共有成员是可访问的,则派生类向基类的转化是可访问的
#10
rjsp2017-05-23 16:06
但是即使是public继承也是访问不到基类的共有成员(只能访问到基类内嵌到派生类的共有成员)
听不懂

另外,public 翻译为“公有”,不是“共有”
#11
韩海03122017-05-23 16:46
回复 10楼 rjsp
打错字了
#12
韩海03122017-05-23 16:48
回复 10楼 rjsp
因为他是派生类啊,怎么访问基类的成员
#13
rjsp2017-05-23 17:33
回复 12楼 韩海0312
你写个示例代码吧,否则我不怎么明白你的意思
1