标签:大神 bsp nbsp out 友元 cout pre ring namespace
之前只注意过访问控制与继承的关系,这边不多说,今天看到代码看到virtual放在private里,并且还有派生类没有override public里的virtual,此时调用时啥情况了,这边有点晕,看下面代码
首先最基本的多态代码
#include <iostream> #include <string> using namespace std; class animal { public: //animal(); //~animal(); virtual void speakout() { cout << "animal voice voice voice" << endl; } }; class cat :public animal { public: //cat(); //~cat(); virtual void speakout() { cout << "cat miao miao miao" << endl; } }; int main() { cat ocat; animal *panimal = &ocat; panimal->speakout(); getchar(); }
运行结果没有任何问题,结果如下:
如果virtual是私有的,代码如下:
#include <iostream> #include <string> using namespace std; class animal { private: //animal(); //~animal(); virtual void speakout() { cout << "animal voice voice voice" << endl; } }; class cat :public animal { private: //cat(); //~cat(); virtual void speakout() { cout << "cat miao miao miao" << endl; } }; int main() { cat ocat; animal *panimal = &ocat; panimal->speakout(); getchar(); }
编译就会报错,报错如下,实际上此时放在private里的时候,virtual有和没有一样,都是类的私有成员,只有类内部成员以及友元能够访问
主要是考虑下面一种特殊情况,基类里有virtual A(),派生类继承的时候没有override A(),切A()会调用私有的private virtual,代码如下:
#include <iostream> #include <string> using namespace std; class animal { public: virtual void speak() { speakout(); } private: //animal(); //~animal(); virtual void speakout() { cout << "animal voice voice voice" << endl; } }; class cat :public animal { private: //cat(); //~cat(); virtual void speakout() { cout << "cat miao miao miao" << endl; } }; int main() { cat ocat; animal *panimal = &ocat; panimal->speak(); getchar(); }
其运行结果如下:
再对比如下代码:
#include <iostream> #include <string> using namespace std; class animal { public: virtual void speak() { speakout(); } private: //animal(); //~animal(); void speakout() { cout << "animal voice voice voice" << endl; } }; class cat :public animal { private: //cat(); //~cat(); void speakout() { cout << "cat miao miao miao" << endl; } }; int main() { cat ocat; animal *panimal = &ocat; panimal->speak(); getchar(); }
其运行结果如下:
说明此时的private里的virtual是不能去掉的,如果去掉的话,speak()调用的是类本身的私有函数speakout(),否则调用的是派生类cat里的speakout()函数
当派生类继承了基类里的public speak(),哪怕没做任何修改,去掉private里的virtual,结果调用也是派生类里的speakout(),代码如下:
#include <iostream> #include <string> using namespace std; class animal { public: virtual void speak() { speakout(); } private: //animal(); //~animal(); void speakout() { cout << "animal voice voice voice" << endl; } }; class cat :public animal { public: virtual void speak() { speakout(); } private: //cat(); //~cat(); void speakout() { cout << "cat miao miao miao" << endl; } }; int main() { cat ocat; animal *panimal = &ocat; panimal->speak(); getchar(); }
运行结果如下:
只能猜测派生类没有继承基类里的public speak(),panimal->speak()调用的是基类里的speak()函数,这时候间接调用的speakout()如果是虚函数则调用派生类的(哪怕是private),否则调用基类的
当继承了基类里的public speak(),panimal->speak()直接就调用了派生类里的speakout(),这时候speakout()是不是虚函数已没有关系
这边的原理我也没搞懂,只知道现在用起来是这样,如果哪位大神知道原理的能和我讲下,不甚感激!!!!!!!!!!!
标签:大神 bsp nbsp out 友元 cout pre ring namespace
原文地址:http://www.cnblogs.com/effortscodepanda/p/6880596.html