学过C++的应该都知道C++中的抽象基类,当我们需要一个基类不能被实例化时,抽象基类就需要上场了。
它通常是通过定义至少一个纯虚函数来实现的,例如下面就是一个抽象基类的例子:
class Abstract { public: Abstract(int data = 0){ m_data = data; }; virtual int getdata() = 0; private: int m_data; };
这时我想要定义一个Abstract的实例,如
int _tmain(int argc, _TCHAR* argv[]) { Abstract a; return 0; }
编译就会出错,提示
error C2259: “Abstract”: 不能实例化抽象类
1> 由于下列成员:
1> “int Abstract::getdata(void)”: 是抽象的
这就是抽象基类的作用,能够被继承,但是不能被直接实例化。
如果我想要实例化抽象基类,怎么办?其实还是有办法的。
比如我如下例般定义一个抽象类的数组并初始化
int _tmain(int argc, _TCHAR* argv[]) { Abstract arr[1] = {3}; return 0; }
进行编译,杠杠的,木有任何问题!
我想用抽象类来调用纯虚函数?也木有任何问题,实际上,C++是允许纯虚函数有定义的。这样我们可以把代码改成如下这样。
class Abstract { public: Abstract(int data = 0){ m_data = data; }; virtual int getdata() = 0; private: int m_data; }; int Abstract::getdata(){ return m_data; } int _tmain(int argc, _TCHAR* argv[]) { Abstract arr[1] = {3}; cout<<arr[0].getdata()<<endl; return 0; }
运行,可以看到结果是3!这正是我们想要的!
但是虽然上述方法能成功,但是如果想用定义好的抽象类直接初始化抽象类还是会出错
Abstract arr[1] = {3}; Abstract a = arr[0];
编译会出错。
用指针或引用来指向对象则可以编译成功
Abstract arr[1] = {3}; Abstract* a = &arr[0];
但是如果用指针或引用调用纯虚函数则运行时会出错
cout<<a->getdata()<<endl;
如果用指针或引用调用非纯虚函数,则能成功运行!
注:本实验在VS2008专业版下进行,不同的环境,结果也可能不同。