关于基类和派生类的构造函数调用
我是C++新手,刚开始学习多态。我知道如果我为派生类创建一个对象,那么派生类和基类的构造函数都会被调用。这是否意味着,当我为派生类创建一个对象时,最终我会得到两个对象 - 一个是由基类的构造函数创建的,另一个是由派生类的构造函数创建的?关于基类和派生类的构造函数调用
任何人都可以解释一下,当我想为派生类创建一个对象时,什么是基类构造函数的工作。
基类构造函数的工作是初始化基类成员变量(考虑基类中private
成员变量的情况)。
当您为派生对象调用构造函数时,最终只能得到一个对象。基类构造函数初始化新对象的基类部分,派生构造函数初始化相同新对象的派生类部分。
构造函数不分配空间并启动对象的实例;他们在分配空间后立即初始化对象。
当您在堆栈上声明对象或使用新的首先保留内存并创建对象,然后执行构造函数,从基础构造函数开始,向上朝向最派生类。
您将最终得到一个包含基类对象的派生类对象。
构造函数不会奇迹般地创建另一个对象实例。它们初始化某段内存,但调用构造函数和分配内存不是一回事 - 后者要么在后台完成(对于具有自动和静态存储持续时间的对象),要么用new
和malloc
(对于具有动态存储时间)。
编辑:之前我生气评论它:“幕后”是一个模糊的方式来说,具有自动或静态存储持续时间的对象的定义确保它获得内存。
无论您是在创建base class
或derived class
的object
,您最终都会得到一个对象。
仅仅因为基类的构造函数被调用,并不意味着你为该调用获得了一个额外的对象。在这里,将执行b ase class constructor
,它通常会设置基类的属性。整个对象将由基类属性和派生类属性组成。
如果你有一个类,那么你将不得不定义一个构造函数或构造函数(在某些情况下你不需要)。构造函数的目的是初始化类数据成员,您为其数据成员赋予一个值。除非数据成员是恰好具有默认构造函数的类的实例,否则您没有给它赋值的任何数据成员将具有未定义的值。
因此,当您创建该类的实例时,编译器将调用相应的构造函数,并且刚刚创建的实例成员将在构造函数中设置它们时使用值初始化数据。
如果您有派生类,则可以向其添加数据成员,但请记住它也有一个继承的成员:基类。因此,当您在派生类中定义构造函数时,必须调用基类的构造函数(以便基类的成员完全初始化),并为派生类自己的数据成员赋值。
因此,您创建派生类的实例,派生类构造函数被invoved。作为其功能的一部分,它调用其基类的构造函数(所以你可能会说两个构造函数,但这是查看它的错误)。
如果您创建基类的实例,则只调用该构造函数。
感谢您的解释。总而言之,如果我为派生类创建一个对象,那么首先调用基类构造函数来初始化基类成员,然后调用派生类构造函数,并创建新的派生类对象。如果我的理解错误,请纠正我。 – newbie 2012-01-09 21:32:02
当我们创建一个对象时,构造函数将被调用。它不在构造函数调用object时被创建。
您可以假定创建对象作为一个函数,而构造函数是另一个函数,它在它内部调用。
假定A是一个基类和B是一个派生类,
类A {
}
类B:公共甲 {
}
我们将以下面的方式为A类创建对象,
A obja;
or
A obja = new A();
在这两种情况下,你可以假设一个函数创建获取调用,
A::Create()
{
A();
}
如果要创建派生B类对象,然后创建B的方法将被调用,
所以在内部创建方法的B看起来会像下面那样,
B::Create()
{
B();
A();
}
所以当我们创建Derived类的对象时首先进行了派生类的初始化,然后Base cla ss初始化发生。这并不意味着对象被创建两次。
将在您创建对象使用的对象中创建对象。
B obj;
或
B obj = new B();
调用构造函数是作为Create函数中调用的构造函数的内部功能。
注:上述代码中的功能仅用于说明目的。
-1我相信用构造函数调用代替Create会比这里解释的问题困惑得多。尤其是在那个人不得不显式调用基本重写函数(细化)而不是构造函数。 – Elemental 2012-01-09 10:57:57
当派生类的对象被创建时,那么该类的构造函数将被首先创建,然后使用基类的构造函数将在调用时被单独的对象调用它将被调用目的。
作为一个对象的生命周期,直到它的构造函数完成,我会说构造函数_do_创建对象(在它们被调用的分配内存区域)。C++不像Java那样,构造函数更像后创建初始化函数(例如,您可以从Java中的构造函数体调用'super')。 – 2012-01-09 21:39:34
@Charles编辑了我的答案,以略微改变词汇量,以免暗示它们类似于java。 – Elemental 2012-01-09 22:10:40