C++祖父默认构造函数调用
C++ Grand Parent default constructor call
我有以下代码,只要我包含 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->width
和 this->height
,Rect
构造函数将为您执行此操作。
在构造函数主体中使用初始值设定项列表而不是赋值的主要优点是,它允许避免对默认构造函数的不必要调用。有关详细说明,请参阅此答案。
它还允许您从没有默认构造函数的类继承(并具有其数据成员)。
如果需要先对值执行某些操作,则可以在构造函数主体中分配值,但是基类(或成员类,如果要初始化数据成员)必须具有默认构造函数。
这样做的原因是,在类的构造函数主体开始执行之前,必须(并且被)调用每个数据成员的构造函数。初始值设定项列表允许您根据您提供的参数选择调用哪个构造函数。如果未在初始值设定项列表中初始化数据成员,则必须先使用其默认构造函数(这就是必须声明它的原因)构造该成员,然后才能在构造函数主体中为其赋值。
相关文章:
- 使用移动调用对等构造函数unique_ptr默认构造函数
- 为什么即使我调用参数化构造函数也会调用默认构造函数?
- 没有用于调用默认构造函数的匹配函数
- 为什么指针对象没有调用默认构造函数
- 调用默认构造函数时不引用它
- 为什么我的对象声明不调用默认构造函数?
- 为什么要尝试调用默认构造函数?
- 在创建对象向量时,不为每个对象唯一调用默认对象构造函数
- std::map 在 [] 上调用默认构造函数,在 insert() 上调用复制构造函数
- 是否可以从移动构造函数调用默认构造函数?
- 编译器错过了无效的构造函数调用,并调用不存在的(或私有的)默认构造函数
- 声明对象而不调用默认构造函数
- 作为参数的空初始值设定项列表不调用默认构造函数
- 如果类划分为单独的文件,则不调用默认构造函数
- 为什么"S x({})"仅在GCC 7/C++1z模式下调用默认构造函数?
- C++ 继承基构造函数,但仍调用默认派生构造函数
- 带有默认参数的宏包装函数调用
- 在返回语句中调用默认构造函数
- 从定义的复制构造函数调用默认(隐式)复制构造函数
- visual C++构造函数调用默认构造函数