首页 > 代码库 > (继承)virtual与访问控制

(继承)virtual与访问控制

之前只注意过访问控制与继承的关系,这边不多说,今天看到代码看到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()是不是虚函数已没有关系

 

 

这边的原理我也没搞懂,只知道现在用起来是这样,如果哪位大神知道原理的能和我讲下,不甚感激!!!!!!!!!!!

  

(继承)virtual与访问控制