【C/C++】纯虚函数

C++虚函数与抽象类详解

问题1:

下面的程序有何错误?

#include <iostream>
using namespace std; 

class Shape
{
	public:
		Shape() {} 
		~Shape() {}
		virtual void Draw() = 0; 
}; 

int main()
{
	Shape s1; 
}

问题2:

什么是虚指针?

问题3:

声明一个类Vehicle,使其成为抽象数据类型。写出类Car和Bus的声明,其中每个类都从Vehicle里派生。使Vehicle成为一个带有两个纯虚函数的ADT,使Car和Bus不是ADT。

问题4:

虚函数的入口地址和普通函数有什么不同?

问题5:

1. C++中如何阻止一个类被实例化?

2. 一般在什么时候构造函数被声明为private呢?

3. 什么时候编译器会生成默认的copy constructor呢?

4. 如果你已经写了一个构造函数,编译器还会生成copy constructor吗?

=======================================================================================

问题1解析

因为Shape类中的Draw函数是一个纯虚函数,所以Shape类是不能实例化一个对象的。Shape s1; 是不可以的,解决办法是把Draw函数修改成一般的虚函数。

答案:

修改后的代码如下:

#include <iostream>
using namespace std; 

class Shape
{
	public:
		Shape() {} 
		~Shape() {}
		virtual void Draw() {}; 
}; 

int main()
{
	Shape s1; 
}

问题2答案

虚指针或虚函数指针是一个虚函数的实现细节。带有虚函数的类中的每一个对象都有一个虚指针指向该类的虚函数表。

问题3答案

class Vehicle 
{
	public:
		virtual void Move() = 0; 
		virtual void Haul() = 0; 
}

class Car : public Vehicle
{
	public:
		virtual void Move(); 
		virtual void Haul(); 
}

class Bus : public Vehicle
{
	public:
		virtual void Move(); 
		virtual void Haul(); 
}

问题4答案

每个虚函数都在vtable中占了一个表项,保存着一条跳转到它的入口地址的指令(实际上就是它的入口地址)。当一个包含虚函数的对象(注意,不是对象的指针)被创建的时候,它在头部附加一个指针,指向vtable中相应的位置。调用虚函数的时候,不管你是用什么指针调用的,它先根据vtable找到入口地址再执行,从而实现了“动态联编”,而不像普通函数那样简单地跳转到一个固定地址。

问题5答案

1. 使用抽象类,或者构造函数被声明为private。

2. singleton模式;阻止某些操作。

3. 只要自己没写,而程序中需要,都会生成。

4. 会生成。

思考:

第2问原提供答案:比如要阻止编译器生成默认的copy constructor的时候。

答案似乎不太合理,似乎并不能阻止生成默认的copy constructor,请看如下代码(可以编译运行)。

#include <iostream>
using namespace std; 

class A 
{
	public:
		static A* GetInstance()
		{
			return new A(); 
		}
	private:
		A() { cout << "test" << endl; }
}; 

int main()
{
	A* a = A::GetInstance(); 
	A b(*a); 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值