c++笔记总结5.19

虚函数的声明virtual只能出现在类定义中函数原型的声明中,不能出现在类外函数体实现的地方

class base
{
	virtual void get( ) ;
}
void base::get( ) 
{
}
virtual void base::get( ) //错误,virtual 关键字只用在类定义里的函数声明中,写函数体时不用。
{
}

小结:
(1)当成员函数做友元函数时,在类外定义时,不加friend
(2)静态成员,在类外定义时,不加static
(3)带默认参数值的成员函数在类内声明时指定,在类外定义时不能再指明参数的默认值
(4)内联函数必须把inline和函数体放在一起才有效
(5)常成员函数在类内类外都加const
实现动态联编的方法:
 (1)首先要声明虚函数
 (2)类之间是公有派生
 (3)通过基类指针或引用调用虚函数
注意:
(1)通过对象名访问虚函数,只能实现静态联编,即利用对象名调用虚函数和调用一般函数没有区别
(2)通常将各类族中具有共性的成员函数声明为虚函数不具备多态性特征的函数不能声明为虚函数
 比如,内联成员函数不能声明为虚函数静态成员函数不能声明为虚函数,友元函数不能声明为虚函数。

例class A
{
public:
	virtual A( ) {};  //error C2633: “A”: “inline”是构造函数的唯一合法存储类
};
class B
{
public:
	virtual static void funb( ) {};  //error C2216: “virtual”不能和“static”一起使用
};
int main( )
{	return 0;
}


(3)构造函数不能是虚函数
(4)析构函数经常被声明为虚函数

构造函数和析构函数内调用虚函数
 采用静态联编,默认调用的虚函数是自己类中实现的虚函数,如果自己类中没有实现虚函数,则调用基类中的虚函数,而不是派生类中实现的虚函数

补充:成员函数调用虚函数 动态联编

虚析构函数
明确:
(1)如果主函数中不使用new delete 时,是否定义虚析构函数时没有差别
(2)派生类对象生存期结束时,先调用派生类的析构函数,再调用基类的析构函数
如果main函数中用new创建了派生类对象:
但析构函数不是虚函数
(1)如果基类中有析构函数
(2)且定义了一个指向基类的指针
(3)当程序用delete借助于基类指针删除派生类对象时,系统只执行基类的析构函数,而不执行派生类的析构函数。

例 普通析构函数在删除动态派生类对象的调用情况
#include<iostream>
using namespace std ;
class A
 { public:
        ~A(){ cout << "A::~A() is called.\n" ; }
 } ;
class B : public A
 { public:
        ~B(){ cout << "B::~B() is called.\n" ; }
} ;
int main() {
    A *Ap = new B ;	
    B *Bp2 = new B ;
    cout << "delete first object:\n" ;
    delete Ap;
    cout << "delete second object:\n" ;
    delete Bp2 ;
} 

运行结果:

 


如果使用了虚析构函数
 用指针释放对象时,基类指针指向哪个层次的对象,则调用的就是哪个类的析构函数,进而释放掉对象空间
如果将基类的析构函数声明为虚函数,由该基类所派生的所有派生类的析构函数都会自动成为虚函数,即使各个类的析构函数名字不同。

虚析构函数在删除动态派生类对象的调用情况
#include<iostream>using namespace std ;
class A
 { public:
        ~A(){ cout << "A::~A() is called.\n" ; }
 } ;
class B : public A
 { public:
        ~B(){ cout << "B::~B() is called.\n" ; }
} ;
int main()
 {  A *Ap = new B ;	
    B *Bp2 = new B ;
    cout << "delete first object:\n" ;
    delete Ap;
    cout << "delete second object:\n" ;
    delete Bp2 ;  } 

运行结果: 


补充:多继承和虚函数 单继承的扩展

 在c++继承体系中,在派生类中可以重写不同基类中的虚函数。

#include <iostream> using namespace std;
class CBaseA{
public:
	virtual void TestA()	
{cout<<"CBaseATestA()"<<endl;	}
};
class CBaseB{
public:
	virtual void TestB()	
{cout<<"CBaseB TestB()"<<endl;	}
};
class CDerived:public CBaseA,public CBaseB{
public:
	virtual void TestA(){	
      cout<<"CDerived TestA()"<<endl;	
     }
	virtual void TestB(){	
cout<<"CDerived TestB()"<<endl;	
    }
};
int main(){CDerived D;
	CBaseA *pb1=&D;
	CBaseB *pb2=&D;
	pb1->TestA();
	pb2->TestB();   	
return 0;  
}
//运行结果:CDerived TestA()
          CDerived TestB()


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是蒸的c

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值