C++调用基类构造函数

liv*_*hak 29 c++ inheritance object

#include <iostream>
#include <stdio.h> 
using namespace std;

// Base class
class Shape 
{
   public:
      void setWidth(int w)
      {
         width = w;
      }
      void setHeight(int h)
      {
         height = h;
      }
      Shape()
      {
    printf("creating shape \n");
      }
      Shape(int h,int w)
      {
     height = h;
         width = w;
         printf("creatig shape with attributes\n");
      } 
   protected:
      int width;
      int height;
};

// Derived class
class Rectangle: public Shape
{
   public:
      int getArea()
      { 
         return (width * height); 
      }
      Rectangle()
      {
     printf("creating rectangle \n");
      }
      Rectangle(int h,int w)
      {
     printf("creating rectangle with attributes \n");
     height = h;
         width = w;
      }
};

int main(void)
{
   Rectangle Rect;

   Rect.setWidth(5);
   Rect.setHeight(7);

   Rectangle *square = new Rectangle(5,5);
   // Print the area of the object.
   cout << "Total area: " << Rect.getArea() << endl;

   return 0;
}
Run Code Online (Sandbox Code Playgroud)

该程序的输出如下

creating shape 
creating rectangle 
creating shape 
creating rectangle with attributes 
Total area: 35
Run Code Online (Sandbox Code Playgroud)

构造两个派生类对象时,我发现它始终是默认情况下首先调用的基类构造函数.是否有一个原因?这就是为什么像python这样的语言坚持基类构造函数的显式调用而不是像C++这样的隐式调用的原因?

mad*_*tya 62

对此的简短回答是,"因为这是C++标准指定的内容".

请注意,您始终可以指定与默认值不同的构造函数,如下所示:

class Shape  {

  Shape()  {...} //default constructor
  Shape(int h, int w) {....} //some custom constructor


};

class Rectangle : public Shape {
  Rectangle(int h, int w) : Shape(h, w) {...} //you can specify which base class constructor to call

}
Run Code Online (Sandbox Code Playgroud)

仅当您未指定要调用的基类时,才会调用基类的默认构造函数.


rer*_*run 13

除非在派生类中显式调用另一个构造函数,否则将调用默认的类构造函数.语言指定了这个.

Rectangle(int h,int w):
   Shape(h,w)
  {...}
Run Code Online (Sandbox Code Playgroud)

将调用其他基类构造函数.


tao*_*ocp 5

构造对象时,始终总是先构造基类子对象,因此,首先调用基类构造函数,然后再调用派生类构造函数。原因是派生类对象包含从基类继承的子对象。您始终需要调用基类构造函数来初始化基类子对象。我们通常在派生类的成员初始化列表上调用基类构造函数。如果未显式调用基类构造函数,则编译将调用基类的默认构造函数来初始化基类子对象。但是,对默认构造函数的隐式调用并不一定总是起作用(例如,如果基类定义了一个没有参数就无法调用的构造函数)。

当对象超出范围时,它将首先调用派生类的析构函数,然后调用基类的析构函数。