struct B{
virtual void f(){ std::cout << "B::f\n"; }
};
struct D: B{
private:
void f(){ std::cout << "D::f\n"; }
};
int main()
{
D d;
B *pd = &d;
pd->f(); //为什么可以调用D的私有函数f()呢?结果是D::f.
}
是不是虚拟继承与访问级别没关系啊?
22 个解决方案
#1
因为:
D d;
B *pd = &d;
指针pd实际上还是指向一个D的对象的,所以调用D的void f()
D d;
B *pd = &d;
指针pd实际上还是指向一个D的对象的,所以调用D的void f()
#2
但是D的void f()是private的呀...
#3
问得好!
#4
B *pd = &d; 动态绑定可以这样实现
#5
这个问题好像在哪个地方有详细的说过,是不是effective c++上面哪?
不记得了...有谁记得么?
不记得了...有谁记得么?
#6
很奇怪的问题
#7
这违反了面向对象的一些规则啊:子类只能扩大范围而不能缩小范围,对于Java来说类似的程序就是非法的,估计当时设计C++的人有自己的想法吧
#8
和你上次的问题一样哦!
#9
是一个很有趣的现象。
private、protected和public是类的访问限定符:public成员在类域内和类域外都能被访问;protected成员在类域内能被访问,但是在类域外,只限于类的派生类访问;private成员只能在类域内被访问。对于类的友元,可以*访问类的成员,上述访问限定符不起作用。
在本题中,在类域外直接通过D的对象d来访问 f 函数是不行的,因为受到private的访问限制。但是通过指向其基类的指针的访问是可以的,因为基类提供了一个访问 virtual 函数 f 的公共接口,通过这个公共接口可以在类域内访问私有成员。
也就是说访问限定符限制的是通过类的成员访问。对于其它方式的成员访问,如上述访问方式或者是友元访问等,类的限定符是不起作用的。
private、protected和public是类的访问限定符:public成员在类域内和类域外都能被访问;protected成员在类域内能被访问,但是在类域外,只限于类的派生类访问;private成员只能在类域内被访问。对于类的友元,可以*访问类的成员,上述访问限定符不起作用。
在本题中,在类域外直接通过D的对象d来访问 f 函数是不行的,因为受到private的访问限制。但是通过指向其基类的指针的访问是可以的,因为基类提供了一个访问 virtual 函数 f 的公共接口,通过这个公共接口可以在类域内访问私有成员。
也就是说访问限定符限制的是通过类的成员访问。对于其它方式的成员访问,如上述访问方式或者是友元访问等,类的限定符是不起作用的。
#10
是一个很有趣的现象。
private、protected和public是类的访问限定符:public成员在类域内和类域外都能被访问;protected成员在类域内能被访问,但是在类域外,只限于类的派生类访问;private成员只能在类域内被访问。对于类的友元,可以*访问类的成员,上述访问限定符不起作用。
在本题中,在类域外直接通过D的对象d来访问 f 函数是不行的,因为受到private的访问限制。但是通过指向其基类的指针的访问是可以的,因为基类提供了一个访问 virtual 函数 f 的公共接口,通过这个公共接口可以在类域内访问包括私有成员在内的成员。
也就是说访问限定符限制的是通过类的成员访问。对于其它方式的成员访问,如上述访问方式或者是友元访问等,类的限定符是不起作用的。
private、protected和public是类的访问限定符:public成员在类域内和类域外都能被访问;protected成员在类域内能被访问,但是在类域外,只限于类的派生类访问;private成员只能在类域内被访问。对于类的友元,可以*访问类的成员,上述访问限定符不起作用。
在本题中,在类域外直接通过D的对象d来访问 f 函数是不行的,因为受到private的访问限制。但是通过指向其基类的指针的访问是可以的,因为基类提供了一个访问 virtual 函数 f 的公共接口,通过这个公共接口可以在类域内访问包括私有成员在内的成员。
也就是说访问限定符限制的是通过类的成员访问。对于其它方式的成员访问,如上述访问方式或者是友元访问等,类的限定符是不起作用的。
#11
这是个好问题,up
#12
to whyglinux(山青水秀):
因为基类提供了一个访问 virtual 函数 f 的公共接口,通过这个公共接口可以在类域内访问包括私有成员在内的成员。
//通过这个接口可以在"类域"内访问private成员.这里可是在main中直接访问呀.
访问限定符限制的是通过类的成员访问。对于其它方式的成员访问
//同上,这里虽然是通过基类的public成员来访问,但是最终定位到的函数却是private的.
//而这是直接在main中访问的.为什么可以呢?
因为基类提供了一个访问 virtual 函数 f 的公共接口,通过这个公共接口可以在类域内访问包括私有成员在内的成员。
//通过这个接口可以在"类域"内访问private成员.这里可是在main中直接访问呀.
访问限定符限制的是通过类的成员访问。对于其它方式的成员访问
//同上,这里虽然是通过基类的public成员来访问,但是最终定位到的函数却是private的.
//而这是直接在main中访问的.为什么可以呢?
#13
no no ?
#14
不太懂,忘高人答疑!!
#15
我觉得好像是虚拟函数表中的指针越过了访问限定符
#16
经过研究,好像只是在编译期检查访问限定
因为pd在编译期是基类指针,因此通过了编译,运行期可能没有访问限定的检查
所以通过虚拟函数表中的指针调用了派生类中的私有函数
因为pd在编译期是基类指针,因此通过了编译,运行期可能没有访问限定的检查
所以通过虚拟函数表中的指针调用了派生类中的私有函数
#17
访问限定只具有编译期语义
#18
编译器问题?还是C++语言本身的问题?这成了一个问题 :)
#19
难道还是C++编译器的问题
还个编译器试试
还个编译器试试
#20
晕,本来就可以这样用啊,跟编译器有什么关系
访问限定只具有编译期语义
访问限定只具有编译期语义
#21
1 D d;
2 B *pd = &d;
3 pd->f();
行3访问的实际上是d的虚函数表,也就是说:对于重载的虚函数,private失去意义
这也许是C++设计者忽略的一个问题。
2 B *pd = &d;
3 pd->f();
行3访问的实际上是d的虚函数表,也就是说:对于重载的虚函数,private失去意义
这也许是C++设计者忽略的一个问题。
#22
众说纷纭,带星的怎么也不回答一下这个问题呀!反正我是说不清楚!我觉得c、c++要比java 难,那就是c,c++最难啦!
#1
因为:
D d;
B *pd = &d;
指针pd实际上还是指向一个D的对象的,所以调用D的void f()
D d;
B *pd = &d;
指针pd实际上还是指向一个D的对象的,所以调用D的void f()
#2
但是D的void f()是private的呀...
#3
问得好!
#4
B *pd = &d; 动态绑定可以这样实现
#5
这个问题好像在哪个地方有详细的说过,是不是effective c++上面哪?
不记得了...有谁记得么?
不记得了...有谁记得么?
#6
很奇怪的问题
#7
这违反了面向对象的一些规则啊:子类只能扩大范围而不能缩小范围,对于Java来说类似的程序就是非法的,估计当时设计C++的人有自己的想法吧
#8
和你上次的问题一样哦!
#9
是一个很有趣的现象。
private、protected和public是类的访问限定符:public成员在类域内和类域外都能被访问;protected成员在类域内能被访问,但是在类域外,只限于类的派生类访问;private成员只能在类域内被访问。对于类的友元,可以*访问类的成员,上述访问限定符不起作用。
在本题中,在类域外直接通过D的对象d来访问 f 函数是不行的,因为受到private的访问限制。但是通过指向其基类的指针的访问是可以的,因为基类提供了一个访问 virtual 函数 f 的公共接口,通过这个公共接口可以在类域内访问私有成员。
也就是说访问限定符限制的是通过类的成员访问。对于其它方式的成员访问,如上述访问方式或者是友元访问等,类的限定符是不起作用的。
private、protected和public是类的访问限定符:public成员在类域内和类域外都能被访问;protected成员在类域内能被访问,但是在类域外,只限于类的派生类访问;private成员只能在类域内被访问。对于类的友元,可以*访问类的成员,上述访问限定符不起作用。
在本题中,在类域外直接通过D的对象d来访问 f 函数是不行的,因为受到private的访问限制。但是通过指向其基类的指针的访问是可以的,因为基类提供了一个访问 virtual 函数 f 的公共接口,通过这个公共接口可以在类域内访问私有成员。
也就是说访问限定符限制的是通过类的成员访问。对于其它方式的成员访问,如上述访问方式或者是友元访问等,类的限定符是不起作用的。
#10
是一个很有趣的现象。
private、protected和public是类的访问限定符:public成员在类域内和类域外都能被访问;protected成员在类域内能被访问,但是在类域外,只限于类的派生类访问;private成员只能在类域内被访问。对于类的友元,可以*访问类的成员,上述访问限定符不起作用。
在本题中,在类域外直接通过D的对象d来访问 f 函数是不行的,因为受到private的访问限制。但是通过指向其基类的指针的访问是可以的,因为基类提供了一个访问 virtual 函数 f 的公共接口,通过这个公共接口可以在类域内访问包括私有成员在内的成员。
也就是说访问限定符限制的是通过类的成员访问。对于其它方式的成员访问,如上述访问方式或者是友元访问等,类的限定符是不起作用的。
private、protected和public是类的访问限定符:public成员在类域内和类域外都能被访问;protected成员在类域内能被访问,但是在类域外,只限于类的派生类访问;private成员只能在类域内被访问。对于类的友元,可以*访问类的成员,上述访问限定符不起作用。
在本题中,在类域外直接通过D的对象d来访问 f 函数是不行的,因为受到private的访问限制。但是通过指向其基类的指针的访问是可以的,因为基类提供了一个访问 virtual 函数 f 的公共接口,通过这个公共接口可以在类域内访问包括私有成员在内的成员。
也就是说访问限定符限制的是通过类的成员访问。对于其它方式的成员访问,如上述访问方式或者是友元访问等,类的限定符是不起作用的。
#11
这是个好问题,up
#12
to whyglinux(山青水秀):
因为基类提供了一个访问 virtual 函数 f 的公共接口,通过这个公共接口可以在类域内访问包括私有成员在内的成员。
//通过这个接口可以在"类域"内访问private成员.这里可是在main中直接访问呀.
访问限定符限制的是通过类的成员访问。对于其它方式的成员访问
//同上,这里虽然是通过基类的public成员来访问,但是最终定位到的函数却是private的.
//而这是直接在main中访问的.为什么可以呢?
因为基类提供了一个访问 virtual 函数 f 的公共接口,通过这个公共接口可以在类域内访问包括私有成员在内的成员。
//通过这个接口可以在"类域"内访问private成员.这里可是在main中直接访问呀.
访问限定符限制的是通过类的成员访问。对于其它方式的成员访问
//同上,这里虽然是通过基类的public成员来访问,但是最终定位到的函数却是private的.
//而这是直接在main中访问的.为什么可以呢?
#13
no no ?
#14
不太懂,忘高人答疑!!
#15
我觉得好像是虚拟函数表中的指针越过了访问限定符
#16
经过研究,好像只是在编译期检查访问限定
因为pd在编译期是基类指针,因此通过了编译,运行期可能没有访问限定的检查
所以通过虚拟函数表中的指针调用了派生类中的私有函数
因为pd在编译期是基类指针,因此通过了编译,运行期可能没有访问限定的检查
所以通过虚拟函数表中的指针调用了派生类中的私有函数
#17
访问限定只具有编译期语义
#18
编译器问题?还是C++语言本身的问题?这成了一个问题 :)
#19
难道还是C++编译器的问题
还个编译器试试
还个编译器试试
#20
晕,本来就可以这样用啊,跟编译器有什么关系
访问限定只具有编译期语义
访问限定只具有编译期语义
#21
1 D d;
2 B *pd = &d;
3 pd->f();
行3访问的实际上是d的虚函数表,也就是说:对于重载的虚函数,private失去意义
这也许是C++设计者忽略的一个问题。
2 B *pd = &d;
3 pd->f();
行3访问的实际上是d的虚函数表,也就是说:对于重载的虚函数,private失去意义
这也许是C++设计者忽略的一个问题。
#22
众说纷纭,带星的怎么也不回答一下这个问题呀!反正我是说不清楚!我觉得c、c++要比java 难,那就是c,c++最难啦!