【问题标题】:About constructor call for base and derived class关于基类和派生类的构造函数调用
【发布时间】:2012-01-09 08:30:22
【问题描述】:

我是 C++ 新手,刚刚开始研究多态性。我知道如果我为派生类创建一个对象,那么派生类和基类的构造函数都会被调用。这是否意味着,当我为派生类创建一个对象时,最终我会得到两个对象——一个是由基类的构造函数创建的,另一个是由派生类的构造函数创建的?

谁能解释一下,当我想为派生类创建一个对象时,基类构造函数的工作是什么。

【问题讨论】:

    标签: c++ oop


    【解决方案1】:

    基类构造函数的工作是初始化基类成员变量(考虑基类中private成员变量的情况)。

    当您为派生对象调用构造函数时,您最终只会得到一个对象。基类构造函数初始化新对象的基类部分,派生构造函数初始化同一个新对象的派生类部分。

    【讨论】:

      【解决方案2】:

      构造函数不分配空间和初始化对象实例;他们在分配空间后立即初始化对象。

      当你在堆栈上声明一个对象或使用 new 首先保留内存并创建对象,然后执行构造函数,从基构造函数开始,向上到最派生的类.

      【讨论】:

      • 由于对象的生命周期在其构造函数完成之前不会开始,我会说构造函数 do 创建对象(在调用它们的分配内存区域中)。 C++ 不像 Java,其中的构造函数更像是创建后的初始化函数(例如,您可以从 Java 的构造函数体中调用 super)。
      • @Charles 已编辑我的答案以稍微更改词汇表,以免暗示它们类似于 java。
      【解决方案3】:

      您最终会得到一个派生类对象,其中包含一个基类对象。

      构造函数不会神奇地创建对象的另一个实例。他们初始化一块内存,但调用构造函数和分配内存不是一回事——后者要么在幕后完成(对于具有自动和静态存储持续时间的对象),要么使用newmalloc(对于具有动态存储持续时间的对象)。

      编辑:在我对它生气之前:“幕后”是一种模糊的表达方式;具有自动或静态存储持续时间的对象的定义可确保它获得内存。

      【讨论】:

        【解决方案4】:

        无论您是创建base classderived class 中的object,最终都会得到一个对象。

        仅仅因为基类构造函数被调用,并不意味着你会为该调用获得一个额外的对象。在这里,将执行 base class constructor,它通常设置基类的属性。整个对象将由基类属性和派生类属性组成。

        【讨论】:

          【解决方案5】:

          如果您有一个类,那么您将必须定义一个或多个构造函数(在某些情况下您不必这样做)。构造函数的目的是初始化类数据成员,你给它的数据成员一个值。任何不给它赋值的数据成员都将有一个未定义的值,除非该数据成员是恰好具有默认构造函数的类的实例。

          因此,当您创建该类的实例时,编译器将调用适当的构造函数,并且您刚刚创建的实例的成员将使用您在构造函数中设置的值初始化数据。

          如果你有一个派生类,你可以给它添加数据成员,但是记住它还有一个继承的成员:基类。因此,当您在派生类中定义构造函数时,您必须调用基类的构造函数(以便基类的成员完全初始化)并将值分配给派生类自己的数据成员。

          所以你创建了一个派生类的实例,派生类的构造函数就被调用了。作为其功能的一部分,它调用其基类的构造函数(因此您可能会说两个构造函数,但这样看是错误的)。

          如果您创建基类的实例,则仅调用该构造函数。

          【讨论】:

          • 感谢您的解释。所以,总而言之,如果我为派生类创建一个对象,那么首先会调用基类构造函数来初始化基类成员,然后调用派生类构造函数并创建新的派生类对象。如果我的理解有误,请纠正我。
          【解决方案6】:

          当我们创建一个对象时,构造函数会被调用。它不是在创建称为对象的构造函数时。

          您可以假设创建对象是一个函数,而构造函数是另一个在其中调用的函数。

          假设 A 是基类,B 是派生类,

          A 级 {

          }

          B 类:公共 A {

          }

          我们将通过以下方式为 A 类创建对象,

          A obja;
          
          or 
          
          A obja = new A();
          

          在这两种情况下,您都可以假设函数 Create 被调用,

          A::Create()
          {
             A();
          }
          

          如果您正在创建派生类 B 对象,则将调用 B 的 Create 方法,

          所以 B 的内部 Create 方法如下所示,

          B::Create()
          {
            B();
            A();
          }
          

          所以当我们创建派生类对象时,首先发生派生类初始化,然后发生基类初始化。这并不意味着对象被创建了两次。

          将为您创建对象的调用创建对象。

          B 对象;

          B obj = 新 B();

          调用构造函数是内部功能,就像在 Create 函数中调用的构造函数一样。

          注意:以上代码中的Create函数仅用于说明目的。

          【讨论】:

          • -1 我相信用 Create 代替构造函数调用比它说明这里的问题更令人困惑。尤其是必须显式调用基覆盖函数(细化)而不是构造函数。
          【解决方案7】:

          当创建派生类的对象时,将首先创建该类的构造函数,然后使用基类的构造函数将由单独的对象在调用时调用它将由该对象调用.

          【讨论】:

            猜你喜欢
            • 2016-07-19
            • 2018-07-16
            • 2018-07-21
            • 2015-08-18
            • 2011-05-03
            • 2016-12-20
            • 2011-09-27
            • 2021-11-11
            • 1970-01-01
            相关资源
            最近更新 更多