虚函数学习(静态联编,动态联编,多态,构造,虚析构,delete)

先几句话:

多态的三个必要条件:

1.存在继承

2.虚方法重写

3.父类(指针或者引用)指向子类对象

 

就一堆代码..

 

 

#include <iostream>

 

using namespace std;

 

class CWorm

{

public:

CWorm() { cout << "CWorm" << endl; }

virtual ~CWorm() { cout << "~CWorm" << endl; }

public:

virtual void speak()

{

cout << "CWorm::speak/n";

}

};

 

class CAnt: public CWorm

{

public:

CAnt() { cout << "CAnt" << endl; }

virtual ~CAnt() { cout << "~CAnt" << endl; }

public:

virtual void speak()

{

cout << "CAnt::speak/n";

}

};

class CSpider: public CWorm

{

public:

CSpider() { cout << "CSpider" << endl; }

virtual ~CSpider() { cout << "~CSpider" << endl; }

public:

virtual void speak()

{

cout << "CSpider::speak/n";

}

};

 

 

class CNormal

{

public:

CNormal() { cout << "CNormal" << endl; }

~CNormal() { cout << "~CNormal" << endl; }

public:

virtual void speak()

{

cout << "CNormal::speak/n";

}

};

 

class CVirtual: public CNormal

{

public:

CVirtual() { cout << "CVirtual" << endl; }

~CVirtual() { cout << "~CVirtual" << endl; }

};

 

class CVirtualEX: public CNormal

{

public:

CVirtualEX() { cout << "CVirtualEX" << endl; }

~CVirtualEX() { cout << "~CVirtualEX" << endl; }

 

};

 

class CNormal2

{

public:

CNormal2() { cout << "CNormal2" << endl; }

virtual ~CNormal2() { cout << "~CNormal2" << endl; }

public:

virtual void speak()

{

cout << "CNormal2::speak/n";

}

};

 

class CVirtual2: public CNormal2

{

public:

CVirtual2() { cout << "CVirtual2" << endl; }

~CVirtual2() { cout << "~CVirtual2" << endl; }

};

 

class CVirtualEX2: public CNormal2

{

public:

CVirtualEX2() { cout << "CVirtualEX2" << endl; }

~CVirtualEX2() { cout << "~CVirtualEX2" << endl; }

};

 

void Call1(CWorm w)

{

w.speak();

}

void Call2(CWorm &w)

{

w.speak();

}

void Call3(CWorm* pw)

{

pw->speak();

}

 

class Cbak

{

public:

Cbak() { cout << "Cbak" << endl; }

virtual ~Cbak() { cout << "~Cbak" << endl; }

public:

virtual Cbak speak()

{

cout << "Cbak::speak/n";

return *this;

}

};

 

int main()

{

/*

CWorm w;

cout << "---------------CWorm w;" << endl;

CSpider s;

cout << "---------------CSpider s;" << endl;

CAnt a;

cout << "---------------CAnt a;" << endl;

// 会调用拷贝构造函数,产生临时对象CWorm t; 这时虚函数表指针不会被拷贝,

// 所以使得函数内部使用的是临时对象t.调用的是CWorm的speak

// 默认并且尽量使用静态联编,也就是编译器编译时就确定函数的地址,不使用寻址间接调用

// 在主程序产生了析构函数

Call1(s);

cout << "---------------Call1(s);" << endl;

Call2(s);

cout << "---------------Call2(s);" << endl;

Call3(&s);

cout << "---------------Call3(&s);" << endl;

 

 

CNormal* pcn = new CVirtual;

delete (CVirtual*)(unsigned long)pcn;

 

// 看起来编译器产生代码的时候,根据delete 目标的对象类型来产生delete代码,不去研究是目标实际的类型.

CNormal* pcn1 = new CVirtual;

delete (CVirtualEX*)(unsigned long)pcn1;

cout << "---------------delete pcn;" << endl;

 

CNormal2* pcn20 = new CVirtual2;

delete pcn20;

 

CNormal2* pcn21 = new CVirtual2;

delete (CVirtual2*)(unsigned long)pcn21;

 

CNormal2* pcn22 = new CVirtual2;

delete (CVirtualEX2*)(unsigned long)pcn22;

 

CNormal2* pcn23 = new CVirtual2;

delete (CSpider*)pcn23;

 

//CNormal* pcn1 = new CVirtual;

//delete (CNormal*)(unsigned long)pcn1;

 

//CNormal* pcn2 = new CVirtual;

//delete pcn2;

cout << "---------------delete pcn2;" << endl;

//CNormal2* pcn211 = (CNormal2*)new CVirtual;

//delete pcn211;

cout << "---------------delete pcn1 & pcn2;" << endl;

 

 

// 看起来编译器产生代码的时候,根据delete 目标的对象类型是否包含虚函数来决定是否根据有虚函数的方式来

// 来产生delete代码

CNormal* pcn112 = (CNormal*)new CVirtual2;

delete pcn112;

CVirtualEX* pcn113 = (CVirtualEX*)new CVirtual2;

delete pcn113;

CSpider* pcn114 = (CSpider*)new CVirtual2;

delete pcn114;

char* pcn115 = (char*)new CVirtual2;

delete [] pcn115;

cout << "---------------delete pcn2 & pcn1;" << endl;

*/

 

 

/*

CWorm *pw = new CWorm;

pw->speak();

 

CWorm *pw2 = new CSpider;

pw2->speak();

 

CSpider s;

CWorm *pw3 = &s;

pw3->speak();

 

CWorm w = s;

w.speak();

 

 

CWorm w2;

memcpy(&w2,pw3,sizeof(s));

((CWorm*)(unsigned long)&w2)->speak(); // 采用了动态联编

cout << "---------------((CWorm*)(char*)&w2)->speak();" << endl;

//((CNormal*)&w2)->speak(); // 因为没有虚函数表,其实就调用了,Spider的析构函数,运行完后堆栈检查通不过

cout << "---------------((CNormal*)&w2)->speak();" << endl;

((CNormal2*)&w2)->speak(); // 能正确调用Spider的speak

cout << "---------------((CNormal2*)&w2)->speak();" << endl;

w2.speak(); // 采用了静态联编

cout << "---------------w2.speak();" << endl;

 

 

CNormal cn;

CNormal* pcn = new CNormal;

CVirtual* pcv = new CVirtual;

cout << "CNormal: cn::sizeof "<< sizeof(cn) << endl;

 

cout << "CNormal::sizeof "<< sizeof(CNormal) << endl;

cout << "CWorm::sizeof "<< sizeof(CWorm) << endl;

cout << "CSpider::sizeof "<< sizeof(CSpider) << endl;

 

 

delete pcv;

cout << "----  delete CVirtual ------"<< endl;

delete pcn;

cout << "----  delete CNormal ------"<< endl;

delete pw2;

delete pw;

*/

 

Cbak b;

Cbak* c = &(b.speak());// 在speak内部调用了拷贝构造函数产生临时对象,在主程序产生了析构函数

cout << "----  Cbak* c = &(b.speak()); ------"<< endl;

 

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值