C++多态练习题

1.虚函数的调用过程

从汇编上面来看:

在这里插入图片描述
[]代表指针解引用操作

1.op指向test对象的首地址(存放vptr),并存放在eax里面;

2.将eax所指之物(虚表的首地址)给edx

3.op所指之物给ecx(test的this指针执向了vptr),并将vptr的地址给了ecx

4.[edx+8],edx代表虚表里面的首地址add函数,+8就是指针偏移8字节,此时指向的print函数,并将print函数给eax

5.call:返回eax,此时eax里面是print函数的地址

2.虚函数例题

例题一

class Object
{
private:
	int value;
public:
	Object(int x=0):value(x){}
	void print()
	{
		cout << "Object::print" << endl;
		add(1);
	}
	virtual void add(int x)
	{
		cout << "Object::add" << x << endl;
	}
};

class Base:public Object
{
private:
	int num;
public:
	Base(int x=0):Object(x+10),num(x){}
	void show()
	{
		cout << "Base::show" << endl;
		print();
	}
	virtual void add(int x)
	{
		cout << "Base::add:" << endl;
	}
};
int main()
{
	Base base;
	base.show();
	return 0;
}

运行结果:
在这里插入图片描述
在这里插入图片描述

例题二

class Object
{
private:
	int value;
public:
	Object(int x = 0) :value(x)
	{
		cout << "Create Object:" << endl;
		add(12);
	}
	~Object()
	{
		cout << "Destory Object:" << endl;
	}
	virtual void add(int x)
	{
		cout << "Object::add" << endl;
	}
	
};

class Base :public Object
{
private:
	int num;
public:
	Base(int x = 0) :Object(x + 10), num(x) 
	{
		cout << "Base Object:" << endl;
		add(1);
	}
	~Base()
	{
		cout << "Destory base:" << endl;
		add(2);
	}
	virtual void add(int x)
	{
		cout << "Base::add:" << endl;
	}
};
int main()
{
	Base base;
	return 0;
}

在这里插入图片描述

  • 构造函数是设置虚表指针
    在没有调用构造函数,对象未被构建时,对象里面的属性都为随机值
  • 析构函数是重置虚表指针
  • 构造函数和析构函数采用静态联编,不进行查表

例题三

class Object
{
public:
	virtual void func(int a = 10)
	{
		cout << "Object::func:a" <<a<< endl;
	}
};
class Base :public Object
{
private:
	virtual void func(int b = 20)
	{
		cout << "Base ::fun:b" << b << endl;
	}
};
int main()
{
	Base base;
	Object* op = &base;
	op->func();
	return 0;
}

在这里插入图片描述
此题目将动态联编和静态联编发挥到了极致
在这里插入图片描述

例题四

class Object
{
private:
	int value = 10;
public:
	Object(int x = 10)
	{
		cout << "create object" << endl;
	}
	void func(int a=10)
	{
		cout << "func::"<<a << value << endl;
	}
	virtual void print()const
	{
		cout << "print" << endl;
	}
};
int main()
{
	Object obj(10);
	Object* op = (Object*)malloc(sizeof(Object));
	op->print();
	op->func();
	return 0;
}

在这里插入图片描述
引发了异常,原因是将对象赋值给空间,系统只负责将数据赋值,不进行虚函数指针的赋值,也就是说虚表指针仍然是随机值,解决方法一:去掉虚函数。
解决办法二:定位new

int main()
{
	Object obj(10);
	Object* op = (Object*)malloc(sizeof(Object));
	*op = obj;
	new(op)Object(obj); //通过拷贝构造对op所指针的空间构造对象
	op->print();
	op->func();
	return 0;
}

在这里插入图片描述

例题四

class Object
{
private:
	int value;
public:
	Object(int x = 0) :value(x)
	{
		cout << "Create Object:" << endl;
		add(12);
	}
	~Object()
	{
		cout << "Destory Object:" << endl;
	}
	virtual void add(int x)
	{
		cout << "Object::add" << endl;
	}

};

class Base :public Object
{
private:
	int num;
public:
	Base(int x = 0) :Object(x + 10), num(x)
	{
		cout << "Base Object:" << endl;
		add(1);
	}
	~Base()
	{
		cout << "Destory base:" << endl;
		add(2);
	}
	virtual void add(int x)
	{
		cout << "Base::add:" << endl;
	}
};
int main()
{
	Object* op = new Base(10);
	op->add(10);
	delete op;
	return 0;
}

在这里插入图片描述
此时我们发现base并没有被析构掉,造成内存泄露,解决办法是将Object的析构函数设置为虚函数
在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我可以为你提供一个简单的继承与多态练习题,希望能帮助你巩固相关知识。 假设有一个图形类 Shape,其中包含一个纯虚函数 getArea(),用于计算该图形的面积。现在要定义两个子类,分别是矩形类 Rectangle 和圆形类 Circle。请完成以下任务: 1. 定义 Shape 类: ```c++ class Shape { public: virtual double getArea() = 0; // 纯虚函数 }; ``` 2. 定义 Rectangle 类,继承自 Shape 类,包含两个成员变量 width 和 height,以及实现 getArea() 函数的具体方法: ```c++ class Rectangle : public Shape { private: double width; double height; public: Rectangle(double w, double h) { width = w; height = h; } double getArea() { return width * height; } }; ``` 3. 定义 Circle 类,同样继承自 Shape 类,包含一个成员变量 radius,以及实现 getArea() 函数的具体方法: ```c++ class Circle : public Shape { private: double radius; public: Circle(double r) { radius = r; } double getArea() { return 3.1415926 * radius * radius; } }; ``` 4. 在主函数中创建一个 Shape 指针数组,分别指向一个 Rectangle 和一个 Circle 对象,并计算它们的面积: ```c++ int main() { Shape* shapes[2]; shapes[0] = new Rectangle(4, 5); shapes[1] = new Circle(3); for (int i = 0; i < 2; i++) { cout << "Area of shape " << i << ": " << shapes[i]->getArea() << endl; delete shapes[i]; } return 0; } ``` 以上就是一个简单的继承与多态练习题,希望能够帮助你巩固相关知识。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

淡蓝色的经典

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

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

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

打赏作者

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

抵扣说明:

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

余额充值