首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++11编译器生成函数

C++11编译器生成函数
EN

Stack Overflow用户
提问于 2013-10-26 12:06:03
回答 2查看 7K关注 0票数 8

说一堂课

class Piece {} ;

如果我是对的,那就相当于:

代码语言:javascript
复制
class Piece {
   //C++ 03
    Piece ();                          //default constructor
    Piece( const Piece&);              //copy constructor
    Piece& operator=(const Piece&);    //copy assignment operator
    ~Piece();                          //destructor

    //Since C++ 11
    Piece(Piece&&);                   //move constructor
    Piece& operator=(Piece&&);        //move assignment operator
};

关于这些我能说些什么?

a)

代码语言:javascript
复制
class Pawn{
    ~Pawn() {}// Only destructor
};

b)

代码语言:javascript
复制
class Bishop{
    Bishop(Bishop&& ) {}// Only move constructor
};

c)

代码语言:javascript
复制
class Knight{
    Knight(Knight&&, int =0) {} // move constructor, when no second arg present
};

d)

代码语言:javascript
复制
class Rook {
    Rook(const Rook& ) {}// Only copy constructor
};

e)

代码语言:javascript
复制
class King{
        King& operator=(const King&) = delete;
    };

根据我的理解,编译器将生成:

  • ( a)默认构造器、复制构造器、复制赋值操作符,(移动构造函数/赋值操作符?)
  • ( b)破坏者
  • ( c)破坏者
  • d)复制赋值操作符和析构函数(移动构造函数/赋值操作符?)
  • ( e)默认构造器,复制构造器,析构函数,(移动构造函数/赋值操作符?)

我在这里是对的还是少了什么?

基本上,当用户不提供时,C++11是否有生成函数的新规则?

EN

回答 2

Stack Overflow用户

发布于 2013-10-26 13:07:38

我将在这里省略一些无关的要点,例如关于unions、基类、大括号或等初始化器等。如果类有任何成员、基类,则.那么答案就会不同。例如,如果您有一个const成员,则隐式声明的赋值运算符将被定义为“删除”。

默认构造函数

class.ctor. class.ctor/5

X的默认构造函数是类X的构造函数,可以不带参数地调用该类构造函数。如果类X没有用户声明的构造函数,则没有参数的构造函数被隐式声明为defaulted。隐式声明的默认构造函数是其类的inline public成员。类X的默认构造函数定义为“删除”,如果.很多观点都与此无关。

因此,在a)和e)没有任何用户声明的ctor的情况下,默认的ctor被声明为默认值。

默认析构函数

class.dtor

4如果类没有用户声明的析构函数,则析构函数被隐式声明为默认值。隐式声明的析构函数是其类的inline public成员。 5类X的默认析构函数定义为已删除,如果.这里有很多不相关的要点

因此,在除a以外的所有情况下,对于用户声明的dtor,如果使用odr,默认的dtor将被隐式声明并隐式定义。

根据those .copy/2+3,如果复制/2+3具有默认参数,则复制-ctor和移动-ctor可能具有附加参数。

复制构造函数

如果没有用户定义的复制- ctor (ctor模板绝不是复制-ctor),则隐式声明复制-ctor。复制/7

如果类定义声明了一个移动构造函数或移动赋值操作符,则隐式声明的复制构造函数被定义为已删除;否则,它将被定义为默认的。如果类具有用户声明的复制赋值操作符或用户声明的析构函数,则不建议使用后一种情况。

也就是说,除了d之外,在所有情况下,对于用户声明的副本ctor,复制ctor都是隐式声明的。在使用用户提供的移动ctor的情况( b)和c)中,复制ctor被定义为已删除。对于用户声明的dtor和e)用户声明的复制分配op,可以将其定义为defaulted,但这是不可取的。

移动构造函数

在这些情况下,move甚至不会被声明为cases .ctor/9。

  • X没有用户声明的复制构造函数,
  • X没有用户声明的副本赋值操作符,
  • X没有用户声明的移动赋值操作符,
  • X没有用户声明的析构函数,并且
  • 移动构造函数不会被隐式定义为已删除。

也有相当多的情况下,它将被定义为删除,但它们不适用于这里。

因此,在任何情况下,move-ctor都是而不是

拷贝赋值算子

副本/18:

如果类定义没有显式声明副本赋值操作符,则将隐式声明一个。如果类定义声明了一个移动构造函数或移动赋值操作符,则隐式声明的复制赋值操作符被定义为已删除;否则,它被定义为defaulted。如果类具有用户声明的复制构造函数或用户声明的析构函数,则不建议使用后一种情况。

在某些情况下,它被定义为已删除,参见class.copy/23,但它们在这里不适用。

复制赋值op在所有情况下都被声明,但是e)用户声明的复制赋值op。在b)和c)中都定义为删除:用户声明的移动ctor;它可以定义为默认的在a)用户声明的dtor和d)用户声明的副本ctor。注意复制机的平行。

移动赋值算子

类似于移动-ctor,如果任意一个ctor.move/20都没有声明移动赋值op:

  • X没有用户声明的复制构造函数,
  • X没有用户声明的移动构造函数,
  • X没有用户声明的副本赋值操作符,
  • X没有用户声明的析构函数,并且
  • 移动赋值运算符不会被隐式定义为已删除。

在某些情况下,它被定义为已删除,参见class.copy/23 (与复制-ctor相同的一段),但它们不适用于这里。

移动赋值-op被隐式声明,并在情况的none中定义为defaulted。

票数 7
EN

Stack Overflow用户

发布于 2013-10-26 13:47:46

因此,看看一些帖子和在线教程,我得出结论:

产生的职能:-

  • C++ 03: 1)默认构造器(只有当用户没有声明构造函数时才生成) 2)复制构造器(仅在用户声明的第5号、第6号时生成) 3)复制赋值操作符(仅在用户未声明的情况下生成5,6 ) 4)破坏者
  • 自C++ 11以来: 5)移动构造器(只有当用户未声明2,3,4,6时才生成) 6)移动赋值操作符(仅在用户未声明2,3,4,5时生成)

所以,为了

a)

代码语言:javascript
复制
class Pawn{ //1, 2, 3
    ~Pawn() {}// Only destructor
};

b)

代码语言:javascript
复制
class Bishop{ //4
    Bishop(Bishop&& ) {}
};

c)

代码语言:javascript
复制
class Knight{ //4
    Knight(Knight&&, int =0) {} 
};

d)

代码语言:javascript
复制
class Rook { //3, 4
    Rook(const Rook& ) {}
};

e)

代码语言:javascript
复制
class King{ //1, 2, 4
        King& operator=(const King&) = delete;
    };

编辑:根据DyP评论:-

在C++11中,

对于a),不建议使用2和3。

对于案例d),不建议使用3。

对于案例e),不建议使用2。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19606492

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档