1、什么是虚继承?
虚继承是为了在多继承的时候避免引发歧义,
比如类A是基类,B继承了A,C也继承了A,当D多继承B,C时,就会有歧义产生了,所以要使用虚拟继承避免重复拷贝。
通俗的讲,虚继承就是为了节约内存的,他是多重继承中的特有的概念。适用与菱形继承形式。
如:类B、C都继承类A,D继承类B和C。为了节省内存空间,可以将B、C对A的继承定义为虚拟继承,此时A就成了虚拟基类。
class A;
class B:vitual public A;
class C:vitual public A;
class D:public B,public C;
2、什么是虚函数继承?
虚函数继承就是覆盖。即基类中的虚函数被派生类中的同名函数所覆盖。
class parent
{
};
class son:public parent
{
};
int main()
{
parent *p=new son();
p->foo();
p->foo1();
return 0;
}
其输出结果是:
foo from son,foo1 from parent
3、什么是纯虚函数?
这样做的意思是包含了纯虚函数的类不能够生成实例,这个类叫做抽象类,也就是说这个类只是包含一些接口定义。而不包括实现,这就要求它的子类必须重新定义纯虚函数的实现。而普通虚函数,子类可以选择重新定义或者不重新定义。也就是实现上面纯虚函数继承的功能,如果基类中的函数没有定义成虚函数,那么最终调用的还是父类的函数,为了总是调用子类的函数,把基类的所有函数都定义成纯虚函数,如vitual func()=0;只定义不实现其方法。
4、什么是虚析构函数?
class A
{
public:
A(){printf("A");}
virtual ~A(){printf("~A");}
};
class B:public A
{
public:
B(){printf("B");}
~B(){printf("~B");}
};
int main()
{
A *p=new B();
delete p;
while(1);
}
{
public:
A(){printf("A");}
virtual ~A(){printf("~A");}
};
class B:public A
{
public:
B(){printf("B");}
~B(){printf("~B");}
};
int main()
{
A *p=new B();
delete p;
while(1);
}
在这个例子中对类A中的析构函数加不加virtual都一样,
加的话输出的结果是AB~B~A,
不加结果是AB~A,
那么如果在B中定义了一个指针并且申请了空间,需要在析构函数中释放,如果这个时候A的析构函数没有加virtual,那么B的析构函数就不会被调用,最后的结果就是B的指针成员变量的空间没有被释放,造成内存泄露,为了保险起见,一般都把基类的析构函数定义成纯虚析构函数,如virtula ~A()=0;但也不要盲目定义各种纯虚函数,因为这个是需要额外的空间花费的。如果这个类需要被继承就加virtual,否则就没必要加virtual
5、什么时候需要加virtual?
如果基类中有一个函数加了virtual,那么就可以把全部函数都加上virtual,因为无论你定义多少个虚函数,1个以上的代价都是4个字节的空间大小,如果这个类不被当做基类,就没有必要浪费空间了。