wss*_*one 0 c++ constructor implicit
源问题来自Usage of this* in make_unique
代码如下,最佳答案是:
在 中
clone(),*this是对 的左值引用,因此您正在从 (对的左值引用) (在 内部)A构造 a ,因此您正在使用 的隐式声明的复制构造函数:AAstd::make_uniqueARun Code Online (Sandbox Code Playgroud)A(A const&);
我很困惑类A有一个虚拟析构函数virtual ~A(){},编译器将不再生成复制构造函数。那么为什么std::make_unique<A>(*this)可以调用 的隐式声明的复制构造函数呢A?
class Base {
public:
virtual ~Base() {}
virtual std::unique_ptr<Base> clone() = 0;
virtual void print() = 0;
};
class A: public Base {
std::string name_;
public:
A(std::string name ){name_ = name;};
std::unique_ptr<Base> clone() override{
return std::make_unique<A>(*this);
};
void print( ) override{
std::cout << "Class A: " << name_;
};
virtual ~A(){};
};
class Factory{
std::unique_ptr<A> type = std::make_unique<A>("MyName");
public:
std::unique_ptr<Base> createInstance(){
return type->clone();
}
};
int main(){
Factory factory;
auto instance = factory.createInstance();
instance->print();
}
Run Code Online (Sandbox Code Playgroud)
我们都知道C++类定义析构函数的规则,编译器不会生成默认的复制构造函数和重载赋值运算符,而这两者的移动版本,看class中的定义A,它定义了virtual ~A(){},所以不会有隐式的要调用的复制构造函数std::make_unique<A>(*this)。
我们都知道c++类定义析构函数的规则,编译器不会生成默认的复制构造函数和重载赋值运算符,
这是不正确的。无论用户声明的析构函数如何,编译器都会声明并定义隐式复制操作。
然而,自 C++11 以来,此行为已被弃用。尽管如此,它并没有从语言中删除(而且我预计它不会很快被删除)。因此,您最多可以期望编译器警告您有关已弃用的行为(例如 Clang 的 with -Wdeprecated),但目前它仍然必须使用隐式复制操作来编译程序。(当然,您可以在 Clang 中将-Wdeprecated警告设置为错误,其他编译器可能有类似的选项。)-Werror=deprecated
这也是为什么遵循 0/3/5 规则如此重要。编译器仍会隐式生成复制操作,即使它们对于具有用户声明的析构函数的类型可能无法正确运行。因此,当您有用户声明的析构函数时,您应该手动定义复制(和移动)操作,或者将它们定义为已删除(如果复制不可能)。
| 归档时间: |
|
| 查看次数: |
149 次 |
| 最近记录: |