防止在复制构造函数中隐式调用基构造函数
Preventing implicit call to base constructor within copy constructor
我想阻止默认构造函数的调用,因此我可以强制用户使用专用构造函数。为此,我只需删除默认构造函数。
当我想为派生类创建复制构造函数时,会出现一个问题。派生类的复制构造函数似乎对父默认构造函数(已删除(进行了隐式调用。编译器不喜欢这样!
有没有办法绕过这个隐式调用?
#include <iostream>
class Base
{
public:
Base() = delete;
Base(int x)
: _x(x)
{
std::cout << "Base's constructor" << std::endl;
}
Base(const Base &other)
{
std::cout << "Base's copy constructor" << std::endl;
this->_x = other._x;
}
protected:
int _x;
};
class Derived : public Base
{
public:
Derived() = delete;
Derived(int x, int y)
: Base(x), _y(y)
{
std::cout << "Derived's constructor" << std::endl;
}
Derived(const Derived &other)
{
// Implict call to Base(), which is deleted, and compilation fails.
std::cout << "Derived's copy constructor" << std::endl;
this->_x = other._x;
this->_y = other._y;
}
protected:
int _y;
};
int main(int argc, char** argv)
{
Derived d(10,10);
Derived d2(d);
}
你的问题是,由于所有构造函数在进入构造函数的主体之前初始化了它们的所有成员
Derived(const Derived &other)
{
// Implict call to Base(), which is deleted, and compilation fails.
std::cout << "Derived's copy constructor" << std::endl;
this->_x = other._x;
this->_y = other._y;
}
其实是
Derived(const Derived &other) : Base(), _y()
{
// Implict call to Base(), which is deleted, and compilation fails.
std::cout << "Derived's copy constructor" << std::endl;
this->_x = other._x;
this->_y = other._y;
}
其中Base()
调用基类默认构造函数。
您需要做的是利用成员初始值设定项列表来调用基类复制构造函数,而不是默认构造函数。 为此,您可以使用
Derived(const Derived &other) : Base(other), _y(other._y)
{
// Implict call to Base(), which is deleted, and compilation fails.
std::cout << "Derived's copy constructor" << std::endl;
// this->_x = other._x; no longer needed as Base(other) takes care of _x
// this->_y = other._y; no longer needed as _y(other._y) takes care of _y
}
您还应该将Base
的复制构造函数更新为
Base(const Base &other) : _x(other._x)
{
std::cout << "Base's copy constructor" << std::endl;
}
您还应该注意,您可以在不定义任何这些复制构造函数的情况下逃脱。 由于尚未定义析构函数,编译器将为这两个类自动生成复制构造函数,并且这些默认复制构造函数将正常工作。
不需要使用=delete
来阻止调用默认构造函数。您可以使用以前的技术将其声明为private
。当然,在这种情况下,由于您希望派生类可以访问它,因此应改为将其设置为protected
。
但您也可以显式构造所需的基类:
Derived(const Derived &other)
: Base(other._x)
, _y(other._y)
{
std::cout << "Derived's copy constructor" << std::endl;
}
相关文章:
- 获取从C++中同一类中的构造函数调用的方法返回的值
- 从具有按值捕获的 lambda 移动构造 std::函数时,移动构造函数调用两次
- 确保所有构造函数调用相同的函数 c++ 设计模式
- 减少复制构造函数调用
- 使用回调函数从构造函数调用虚拟/派生方法的替代方法?
- 在 Google 测试中,我可以从构造函数调用 GetParam() 吗?
- C++ - 从另一个类构造函数调用类构造函数
- 在C++中初始化带有和不使用构造函数调用的对象有什么区别
- 是否可以从移动构造函数调用默认构造函数?
- 在模板生成器模式中分解重复的构造函数调用
- std::atexit 从全局对象的构造函数调用时的排序
- 对构造函数调用的约束
- 编译器错过了无效的构造函数调用,并调用不存在的(或私有的)默认构造函数
- 用构造函数调用填充向量
- 创建指针时是否没有构造函数调用
- 使用 emplace_back 避免移动构造函数调用的最佳方法?
- C++ 抽象类构造函数调用
- 为什么函数参数将带有参数的构造函数调用
- 为什么比“构造函数”调用更多的“解构器”调用
- 将对象传递给函数并不是导致构造函数调用