虚函数调用的几种方式

虚函数调用的几种方式

/*

* 虚函数的三种调用

* 1: 指针

* 2: 引用

* 3: 对象(不能实现多态)

*/

#include

//继承,默认情况下class是私有继承 struct默认是公有继承

//虚函数可以调用成员函数

//多态调用依赖于指针 或 引用调用

//对象的调用有副本机制,会调用拷贝构造 拷贝一个父类 无法实现多态

//p->go(); //多态调用

//p->myclass::go(); //原生调用

//虚函数重载和返回值无关 和参数的类型 个数 顺序有关

//虚函数被继承下来了还是虚函数

//如果要使用被继承的虚函数 不允许出现虚函数重载和覆盖

//多态可以跨类 爷爷辈的指针 可以存储孙子辈的地址 父辈拔针的地址

class myclass

{

public:

int i;

virtual void go()

{

i = 0;

show();

}

void show()

{

std::cout << "myclass->show()" << std::endl;

}

virtual ~myclass()

{

// 不加virtual 会造成内存泄漏

}

};

class newmyclass: public myclass

{

public:

void go()

{

std::cout << "newmyclass->go()" << std::endl;

}

void show()

{

std::cout << "newmyclass->show()" << std::endl;

}

void put()

{

std::cout << "newmyclass->put()" << std::endl;

}

};

// 1: 指针

void test1(myclass *p)

{

p->go();

}

// 2: 引用

void test2(myclass &p)

{

p.go();

}

// 3: 对象

void test3(myclass my)

{

my.go();

}

int main()

{

myclass my;

my.go(); // 正常调用父类的go函数

newmyclass newmy;

newmy.go(); // 正常调用子类的go函数

myclass *pmy(nullptr);

pmy->show(); // 空指针可以调用show操作

//pmy->go(); // 空指针无法调用go函数,因为myclass类,没有实例化为对象,go函数内部操作了对象的内部变量,此时该内部变量并没有构造出来

myclass *p = new newmyclass;

p->go(); // 调用子类的go函数

p->myclass::go(); // 指定调用父类的go函数

std::cout << typeid(p).name() << std::endl; // p的类型为父类类型指针 class myclass *

std::cout << typeid(*p).name() << std::endl; // *p的类型为子类类型 class newmyclass

test1(p); // 调用子类的go函数

test1(&my); // 调用父类的go函数

test1(&newmy); // 调用子类的go函数

// 引用在语言内部用指针实现,引用是操作受限了的指针(仅容许取内容操作)

test2(*p); // 调用子类的go函数

test2(my); // 调用父类的go函数

test2(newmy); // 调用子类的go函数

// 对象作为参数,会使用拷贝构造函数,形成对象的副本

test3(*p); // 调用父类的go函数

test3(my); // 调用父类的go函数

test3(newmy); // 调用父类的go函数

//std::cout << "mytest" << std::endl;

system("pause");

return 0;

}

运行结果:


BTY的主要含义
衬衫怎么叠不出褶 3张图让你迅速学会叠衬衫