Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 当子';s被隐式删除_C++_Inheritance_C++11_Move_Using Declaration - Fatal编程技术网

C++ 当子';s被隐式删除

C++ 当子';s被隐式删除,c++,inheritance,c++11,move,using-declaration,C++,Inheritance,C++11,Move,Using Declaration,在GCC 4.6中,即使子级的赋值运算符由于移动构造函数而被隐式删除,也可以继承父级的赋值运算符。在以后的GCC版本(以及Clang)中,这已经不可能了。让子类使用父类的赋值运算符的正确方法是什么 struct A { A & operator=(A const & other) = default; }; struct B : public A { B() {} B(B && other) {} using A::operator=; };

在GCC 4.6中,即使子级的赋值运算符由于移动构造函数而被隐式删除,也可以继承父级的赋值运算符。在以后的GCC版本(以及Clang)中,这已经不可能了。让子类使用父类的赋值运算符的正确方法是什么

struct A
{
  A & operator=(A const & other) = default;
};

struct B : public A
{
  B() {}
  B(B && other) {}

  using A::operator=;
};

int main()
{
  B b1, b2;
  b1 = b2; // error: use of deleted function because B's operator= is implicitly deleted due to move constructor
  return 0;
}

已删除的函数仍会声明,仅删除定义。在类定义中扩展:

struct B : A {
   using A::operator=;               // A& operator=(const A&)
   B& operator=(const B&) = delete;
};
此时,您可以注意到在派生类型中有两个
运算符=
的声明,第一个声明(通过使用声明引入范围)采用
常量a&
参数,而第二个声明采用
常量B&
并被删除

稍后尝试分配时:

B b1, b2;
b1 = b2;
编译器可以看到这两个声明,而第二个声明更匹配。因为它被标记为已删除,所以会出现错误。另一方面,如果您指定了一个
a
对象,该对象将按预期工作:

B b1, b2;
b1 = static_cast<A&>(b2); // works, BUT...

这将取决于在将派生类型分配给自身时希望发生什么。如果您希望子赋值操作符像“正常”一样工作,尽管移动操作符禁止隐式生成,您只需使用以下命令将子赋值返回到类中:
B&运算符=(B常量&)=默认值

这可能相当于GCC4.6所做的。我相信GCC4.6并没有按照标准要求正确地抑制生成的运算符,所以您可能只是得到了正常的赋值运算符行为,以及使用声明所引入的基类中的任何重载

如果您实际上只想分配类的基本部分,则需要实现自己的赋值运算符:

B运算符=(B常量和该运算符){
静态_cast(*此)=那个;
归还*这个;
}

不幸的是,我现在没有GCC4.7来试用,但是如果您在派生类中实际得到基类赋值运算符,我也不会感到惊讶,但是派生类的deleted赋值运算符更适合您的示例。您可以通过在main()中尝试这一行来测试这一点:
b1=静态铸造(b2)

struct B : A {
   // ...
   B& operator=(const B&) = default;
};
B &operator=( B const & ) = default; B &operator=( B const &that ) { static_cast<A&>(*this) = that; return *this; } b1 = static_cast<A const&>(b2);