关于抽象基类中的 构造函数和析构函数

1.他也不实例化对象 写那个干啥 2.我就是把它去掉了 也能运行 为什么 3,程序中构造函数是普通的 为什么析构函数写成了 虚函数形式?
#include <iostream>
using namespace std;
class Shape
{
public:
Shape(void) { }
virtual ~Shape(void) { }
virtual double area() = 0; // 纯虚函数
};
class Rect : public Shape
{
public:
Rect(int l, int w) : m_l(l), m_w(w) { }
virtual ~Rect(void) { }
virtual double area() // 实现纯虚函数
{
return m_l * m_w;
}
private:
double m_l;
double m_w;
};
class Square : public Shape
{
public:
Square(int l) : m_l(l) { }
virtual ~Square(void) { }
virtual double area() // 实现纯虚函数
{
return m_l * m_l;
}
private:
double m_l;
};
int main()
{
Shape *s1, *s2;
s1 = new Rect(3, 4);
cout << s1->area() << endl;
s2 = new Square(5);
cout << s2->area() << endl;
delete s1;
delete s2;
return 0;
}

我来回答吧:
#1.他也不实例化对象 写那个干啥
在你这个例子中的确没有什么用。虽然有纯虚函数的类不能被实例化,但是它可以被继承,子类的构造过程就调用父类的构造函数的。所以当虚类有构造逻辑时,写构造函数是正常的。

#2.我就是把它去掉了 也能运行 为什么
你的这个例子因为构造函数为空,其实和没写一样。删除后,编译器其实会自动生成一个构造函数的,也是什么都不做,一个空函数。

#3.程序中构造函数是普通的 为什么析构函数写成了 虚函数形式?
虚析构函数是为了确保类的实例能够被正确析构。因为非虚函数的调用的代码是在链接期绑定的,而完全可能出现本来是类SubClass的实例,你转换为FatherClass的指针了,这个时候会导致父类的析构函数被调用,而导致错误的析构。所以C++的书上基本上都是建议将可能被继承的类的析构函数声明为虚函数。(虚函数的调用是运行期绑定的)追问

非常感谢你的回答 关于:子类的构造过程就调用父类的构造函数的 这句话 我不是很理解 能帮忙解释一下吗 另外 我抽象基类构造函数一般情况是不是都为空呢? 不为空的能举个简单的例子吗 采纳后我回再补20分 的 谢谢了

追答

比如类 A 有成员 int i,有纯虚方法;
类B 继承类A,类C继承类A,那么如果你不给类A写构造函数,你不就得在类B和类C中写变量i的构造逻辑了么?如果你写了类A的构造函数,那么在类B和类C的构造时,是会先调用你类的构造函数,然后再构造自己类的成员的。类的继承都是按照这个构造顺序。

至于是不是虚类就是空构造的这个问题,的确是,大多数情况下都是空的。

温馨提示:内容为网友见解,仅供参考
第1个回答  2013-03-12
无参构造函数,写不写都可以,即使不写,编译器也会给你加一个默认构造函数的
析构函数写成虚函数,在这个例子当中没有发现这么写的必要,但是这样写有一个好处
就是当派生类中析构函数有操作时,调用基类函数指针进行delete操作,同样可以执行派生类析构函数
所以在基类析构函数没有任何操作情况下,把它定义成虚函数
第2个回答  2013-03-12
> 1.他也不实例化对象 写那个干啥
看看抽象的解释吧。主函数中的s1和s2,实例是Rect和Square。但是你并不需要把s1和s2定义成Rect和Square。现在只有Rect和Square,要是以后还有五边形,六边形,圆形等等呢。所以只要定义Shape就可以。

> 2.我就是把它去掉了 也能运行 为什么
因为它是抽象的,具体实现在子类中,基类实际上相当于"Interface"的作用了。

> 3,程序中构造函数是普通的 为什么析构函数写成了 虚函数形式?
解释起来稍多些,网上有专业的解释,你百度一下“虚析构函数”有很多介绍。追问

谢谢你 我对问题1 的表述可能不太清楚
我意思是 构造函数和析构函数是和实例化的对象有关的
抽象基类并没有实例化对象 那我为什么还要在基类中写构造函数和析构函数? 谢谢

追答

构造函数可以用来初始化成员变量的。你现在没有成员变量罢了。
即使你不写构造函数,编译器也会自动给你产生一个没有参数的构造函数的。

关于抽象基类中的 构造函数和析构函数
你好!无参构造函数,写不写都可以,即使不写,编译器也会给你加一个默认构造函数的 析构函数写成虚函数,在这个例子当中没有发现这么写的必要,但是这样写有一个好处 就是当派生类中析构函数有操作时,调用基类函数指针进行delete操作,同样可以执行派生类析构函数 所以在基类析构函数没有任何操作情况...

秋招C++八股--类中的重要函数
构造函数和析构函数是否能声明为虚函数?构造函数不能,因为它们只在对象生命周期内运行一次,不属于动态行为。析构函数通常声明为虚函数以支持动态绑定。纯虚析构函数在基类中声明纯虚函数,表示抽象类,不能直接实例化。C++中的构造函数包括默认构造函数、带参数构造函数、拷贝构造函数和移动构造函数。拷贝...

关于c++抽象类的问题
椭圆类,矩形类,三角形类 里 这些 虚函数 都要 重新写成 具体的 计算函数。使用中就方便了。面积 就调 Area(), 周长 就调 Perimeter().抽象类为什么不能被实例化 -- 语法规定不能被实例化,因为它是抽象的概念性的,没有实际意义的,里面的 虚函数 等待 重写,没实用价值。构造、析构函数 ...

java 中的语法到底指的什么?
调用基类的构造函数构造基类对象 实例变量的初始化 构造函数的其余部分 Java使用abstract关键字修饰抽象方法或抽象类 C++的对等语法是“纯虚函数”和“抽象类”两者都使用抽象类作为继承层次中的基类,提供一般概念,由子类实现其抽象方法,且抽象类都不能被直接实例化为对象 Java中有final关键字,修饰类、...

什么情况下,类的析构函数应该声明为虚函数?为什么?
虚析构函数是为了解决这样的一个问题:基类的指针指向派生类对象,并用基类的指针删除派生类对象。如果某个类不包含虚函数,那一般是表示它将不作为一个基类来使用。当一个类不准备作为基类使用时,使析构函数为虚一般是个坏主意。因为它会为类增加一个虚函数表,使得对象的体积翻倍,还有可能降低其可...

析构函数的作用
因此,除非类不打算作为基类使用,否则声明析构函数为虚是最佳实践。此外,声明纯虚析构函数可以创建抽象类,这类类不能被实例化,但可以作为基类供派生类继承。考虑一个表示敌人目标的类enemytarget,其中包含一个静态成员变量来跟踪对象总数。在派生类enemytank中,同样使用类似的方法跟踪坦克的总数。在...

抽象类的构造器运行问题,(满意我再加50)
从内存分配上来说,比如"男人",就是先分配出"人"的特性所要的内存空间(不论是public,protected,还是private的字段,都是它的特性).再添加"男人"特有的特性 定义一个类从其他类派生时,派生类隐式获得基类的除构造函数和析构函数以外的所有成员。(注意,是除构造和析构,以外的所有成员,包括字段,方法,...

C语言,执行 link.exe 时出错
执行link.exe时出错,是设置错误造成的,解决方法如下:1、首先重新建立工程文件。2、然后选择win32 console application建立。3、接着在打开的页面中,选择工程——设置——连接。4、在工程选项框中找到\/subsystem:windows \/,将其改为\/subsystem:console \/,然后点“确定”。5、最后点击运行程序,如下...

一个VC++6.0编译问题
试图调用一个纯虚函数的构造函数或析构函数的抽象基类将导致LNK2001因为按照定义一个纯虚函数没有基类执行。全球唯一的函数和变量是公开的。职能宣布与静态修饰的定义文件的范围。静态变量具有相同的限制。试图访问任何静态变量以外的文件,他们被宣布可能会导致出现一个编译错误或LNK2001 。一个变量的函数内...

《面向对象程序设计》高手进~~~!!
4.派生类的构造函数执行之前必先调用基类的构造函数,建立基类的一个对象,当对象生命周期完结之时,先调用派生类的析构函数释放其资源,而后调用基类的析构函数。5.基类中的构造函数和析构函数都不能被继承。派生类的构造函数:派生类中的新的或者改造来的成员则需要自己的构造函数,从基类中继承来的则...

相似回答