C++祖父默认构造函数调用

C++ Grand Parent default constructor call

本文关键字:函数调用 默认 C++      更新时间:2023-10-16

我有以下代码,只要我包含 Rect 默认构造函数,它就可以正常运行。但是,如果我注释掉它,希望它只会"跳过"到它无法编译的 Shape 默认构造函数。

#include <cstdio>
class Shape
{
public:
    Shape()
    {
        printf("Shape default calledn");
    }
};
class Rect : public Shape
{
public:
    int width;
    int height;
    
    Rect()
    {
        printf("Rect default calledn");
    }
    Rect(int width, int height)
    {
        this->width = width;
        this->height = height;
    }
    int area()
    {
        return width*height; 
    }
};
class Square : public Rect
{
public:
    Square(int width)
    {   
        printf("Square constructor called.n");
        this->width = width;
        this->height = width;
    }
};
int main(int argv, char** argc)
{
    printf("...n");
    Square r = Square(10);
    printf("Area: %dn", r.area());
    return 0;
}

当程序运行和编译时,我得到以下输出

形状默认值调用

矩形默认值调用

方形构造函数调用。

面积: 100

我希望简单地删除Rect默认构造函数并获得

形状默认值调用

方形构造函数调用。

面积: 100

因为 rect 默认构造函数所做的只是坐在那里满足 Clang 的错误。它不打算做任何额外的事情。有没有办法做到这一点?

应使用成员初始值设定项列表语法使用参数调用适当的Rect构造函数:

Square(int width) : Rect(width, width)
{
    printf("Square constructor called.n");
}

请注意,您不需要手动分配给 this->widththis->heightRect构造函数将为您执行此操作。

在构造函数主体中使用初始值设定项列表而不是赋值的主要优点是,它允许避免对默认构造函数的不必要调用。有关详细说明,请参阅此答案。

它还允许您从没有默认构造函数的类继承(并具有其数据成员)。

如果需要先对值执行某些操作,则可以在构造函数主体中分配值,但是基类(或成员类,如果要初始化数据成员)必须具有默认构造函数。

这样做的原因是,在类的构造函数主体开始执行之前,必须(并且被)调用每个数据成员的构造函数。初始值设定项列表允许您根据您提供的参数选择调用哪个构造函数。如果未在初始值设定项列表中初始化数据成员,则必须先使用其默认构造函数(这就是必须声明它的原因)构造该成员,然后才能在构造函数主体中为其赋值。