虚函数继承、虚继承、虚析构函数、纯虚函数

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
{
public:
vitual void foo(){cout < <"foo from parent";};
void foo1(){cout < <"foo1 from parent";};
};
class son:public parent
{
void foo(){cout < <"foo from son";};
void foo1(){cout < <"foo1 from son";};
};
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);
}
在这个例子中对类A中的析构函数加不加virtual都一样,
加的话输出的结果是AB~B~A,
不加结果是AB~A,
那么如果在B中定义了一个指针并且申请了空间,需要在析构函数中释放,如果这个时候A的析构函数没有加virtual,那么B的析构函数就不会被调用,最后的结果就是B的指针成员变量的空间没有被释放,造成内存泄露,为了保险起见,一般都把基类的析构函数定义成纯虚析构函数,如virtula ~A()=0;但也不要盲目定义各种纯虚函数,因为这个是需要额外的空间花费的。如果这个类需要被继承就加virtual,否则就没必要加virtual

 

5、什么时候需要加virtual?

如果基类中有一个函数加了virtual,那么就可以把全部函数都加上virtual,因为无论你定义多少个虚函数,1个以上的代价都是4个字节的空间大小,如果这个类不被当做基类,就没有必要浪费空间了。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值