一个类有多少个默认方法?

时间:2021-09-26 08:12:53

Sorry, this might seem simple, but somebody asked me this, and I don't know for certain.

抱歉,这看起来很简单,但是有人问我这个,我不确定。

An empty C++ class comes with what functions?

一个空的c++类带有什么函数?

Constructor, Copy Constructor, Assignment, Destructor?

构造函数,复制构造函数,赋值,析构函数?

Is that it? Or are there more?

是它吗?或者有更多的吗?

5 个解决方案

#1


44  

In C++03 there are 4:

在c++ 03中有4个:

  • Default constructor: Declared only if no user-defined constructor is declared. Defined when used

    默认构造函数:只有在没有声明用户定义的构造函数时才声明。定义使用时

  • Copy constructor - declared only if the user hasn't declared one. Defined if used

    复制构造函数——只有当用户没有声明时才声明。如果使用定义

  • Copy-assignment operator same as above

    复制分配操作符与上面相同

  • Destructor same as above

    析构函数与上面一样

In C++11 there are two more:

在c++ 11中,还有两个:

  • Move constructor
  • 转移构造函数
  • Move-assignment operator
  • Move-assignment运营商

It is also possible that the compiler won't be able to generate some of them. For example, if the class contains, for example, a reference (or anything else that cannot be copy-assigned), then the compiler won't be able to generate a copy-assignment operator for you. For more information read this

也有可能编译器不能生成其中的一些。例如,如果类包含引用(或任何不能被复制分配的内容),那么编译器将无法为您生成复制分配操作符。有关更多信息,请阅读本文

#2


12  

If I define the following class

如果我定义了下面的类

class X
{};

The compiler will define the following methods:

编译器将定义以下方法:

X::X()  {}                    // Default constructor. It takes zero arguments (hence default).
X::~X() {}                    // Destructor
X::X(X const& rhs) {};        // Copy constructor
X& operator=(X const& rhs)
{return *this;}              // Assignment operator.

Note:
The default constructor is not built if ANY constructor is defined.
The other methods are not built if the user defines an alternative.

注意:如果定义了任何构造函数,则不构建默认构造函数。如果用户定义了另一种方法,则不构建其他方法。

What is slightly more interesting is the default implementation when we have members and a base:

更有趣的是,当我们有成员和基数时,默认实现是:

class Y: public X
{
    int    a;      // POD data
    int*   b;      // POD (that also happens to be a pointer)
    Z      z;      // A class
};

// Note: There are two variants of the default constructor.
//       Both are used depending on context when the compiler defined version
//       of the default constructor is used.
//
//       One does `default initialization`
//       One does `zero initialization`

// Objects are zero initialized when
//   They are 'static storage duration'
//   **OR** You use the braces when using the default constructor
Y::Y()      // Zero initializer
    : X()   // Zero initializer
    , a(0)
    , b(0)
    , z()   // Zero initializer of Z called.
{}

// Objects are default initialized when
//    They are 'automatic storage duration'
//    **AND** don't use the braces when using the default constructor
Y::Y()
    :X    // Not legal syntax trying to portray default initialization of X (base class)
    //,a  // POD: uninitialized.
    //,b  // POD: uninitialized.
    ,z    // Not legal syntax trying to portray default initialization of z (member)
{}
//
// Note: It is actually hard to correctly zero initialize a 'automatic storage duration'
//       variable (because of the parsing problems it tends to end up a a function
//       declaration). Thus in a function context member variables can have indeterminate
//       values because of default initialization. Thus it is always good practice to 
//       to initialize all members of your class during construction (preferably in the
//       initialization list).
//
// Note: This was defined this way so that the C++ is backward compatible with C.
//       And obeys the rule of don't do more than you need too (because we want the C++
//       code to be as fast and efficient as possible.


Y::Y(Y const& rhs)
    :X(rhs)              // Copy construct the base
    ,a(rhs.a)            // Copy construct each member using the copy constructor.
    ,b(rhs.b)            // NOTE: The order is explicitly defined
    ,z(rhs.z)            //       as the order of declaration in the class.
{}

Y& operator=(Y const& rhs)
{
    X::operator=(rhs);   // Use base assignment operator
    a  = rhs.a;          // Use the assignment operator on each member.
    b  = rhs.b;          // NOTE: The order is explicitly defined
    z  = rhs.z;          //       as the order of declaration in the class.
    return(*this);
}

Y::~Y()
{
    Your Code first
}
// Not legal code. Trying to show what happens.
  : ~z()
  , ~b() // Does nothing for pointers.
  , ~a() // Does nothing for POD types
  , ~X() ; // Base class destructed last.

#3


4  

Just to expand on Armen Tsirunyan answer here are the signatures for the methods:

以下是这些方法的签名:

// C++03
MyClass();                                     // Default constructor
MyClass(const MyClass& other);                 // Copy constructor
MyClass& operator=(const MyClass& other);      // Copy assignment operator
~MyClass();                                    // Destructor

// C++11 adds two more
MyClass(MyClass&& other) noexcept;             // Move constructor
MyClass& operator=(MyClass&& other) noexcept;  // Move assignment operator

#4


0  

Is that it?

是它吗?

Yes thats it.

是的这是它。

Compiler generates by default

编译器生成默认情况下

  • A default constructor
  • 一个默认的构造函数
  • A copy constructor
  • 一个拷贝构造函数
  • A copy assignment operator
  • 拷贝赋值运算符
  • A destructor
  • 一个析构函数

for a class

为一个类

You can see the default constructor, the copy constructor and the assignment operator being generated by default when you use -ast-dump option of Clang

您可以看到默认构造函数、复制构造函数和在使用- astdump选项时默认生成的赋值操作符。

prasoon@prasoon-desktop ~ $ cat empty.cpp && clang++ -cc1 -ast-dump empty.cpp
class empty
{};

int main()
{
   empty e;
   empty e2 = e;
   {
     empty e3;
     e3 = e;
   }

}
typedef char *__builtin_va_list;
class empty {
    class empty;
    inline empty() throw(); //default c-tor
    //copy c-tor
    inline empty(empty const &) throw() (CompoundStmt 0xa0b1050 <empty.cpp:1:7>)

    //assignment operator   
    inline empty &operator=(empty const &) throw() (CompoundStmt 0xa0b1590 <empty.cpp:1:7>
  (ReturnStmt 0xa0b1578 <col:7>
    (UnaryOperator 0xa0b1558 <col:7> 'class empty' prefix '*'
      (CXXThisExpr 0xa0b1538 <col:7> 'class empty *' this))))


};

#5


0  

Default methods assigned by compiler for a empty class:

编译器为空类分配的默认方法:

http://cplusplusinterviews.blogspot.sg/2015/04/compiler-default-methods.html

http://cplusplusinterviews.blogspot.sg/2015/04/compiler-default-methods.html

#1


44  

In C++03 there are 4:

在c++ 03中有4个:

  • Default constructor: Declared only if no user-defined constructor is declared. Defined when used

    默认构造函数:只有在没有声明用户定义的构造函数时才声明。定义使用时

  • Copy constructor - declared only if the user hasn't declared one. Defined if used

    复制构造函数——只有当用户没有声明时才声明。如果使用定义

  • Copy-assignment operator same as above

    复制分配操作符与上面相同

  • Destructor same as above

    析构函数与上面一样

In C++11 there are two more:

在c++ 11中,还有两个:

  • Move constructor
  • 转移构造函数
  • Move-assignment operator
  • Move-assignment运营商

It is also possible that the compiler won't be able to generate some of them. For example, if the class contains, for example, a reference (or anything else that cannot be copy-assigned), then the compiler won't be able to generate a copy-assignment operator for you. For more information read this

也有可能编译器不能生成其中的一些。例如,如果类包含引用(或任何不能被复制分配的内容),那么编译器将无法为您生成复制分配操作符。有关更多信息,请阅读本文

#2


12  

If I define the following class

如果我定义了下面的类

class X
{};

The compiler will define the following methods:

编译器将定义以下方法:

X::X()  {}                    // Default constructor. It takes zero arguments (hence default).
X::~X() {}                    // Destructor
X::X(X const& rhs) {};        // Copy constructor
X& operator=(X const& rhs)
{return *this;}              // Assignment operator.

Note:
The default constructor is not built if ANY constructor is defined.
The other methods are not built if the user defines an alternative.

注意:如果定义了任何构造函数,则不构建默认构造函数。如果用户定义了另一种方法,则不构建其他方法。

What is slightly more interesting is the default implementation when we have members and a base:

更有趣的是,当我们有成员和基数时,默认实现是:

class Y: public X
{
    int    a;      // POD data
    int*   b;      // POD (that also happens to be a pointer)
    Z      z;      // A class
};

// Note: There are two variants of the default constructor.
//       Both are used depending on context when the compiler defined version
//       of the default constructor is used.
//
//       One does `default initialization`
//       One does `zero initialization`

// Objects are zero initialized when
//   They are 'static storage duration'
//   **OR** You use the braces when using the default constructor
Y::Y()      // Zero initializer
    : X()   // Zero initializer
    , a(0)
    , b(0)
    , z()   // Zero initializer of Z called.
{}

// Objects are default initialized when
//    They are 'automatic storage duration'
//    **AND** don't use the braces when using the default constructor
Y::Y()
    :X    // Not legal syntax trying to portray default initialization of X (base class)
    //,a  // POD: uninitialized.
    //,b  // POD: uninitialized.
    ,z    // Not legal syntax trying to portray default initialization of z (member)
{}
//
// Note: It is actually hard to correctly zero initialize a 'automatic storage duration'
//       variable (because of the parsing problems it tends to end up a a function
//       declaration). Thus in a function context member variables can have indeterminate
//       values because of default initialization. Thus it is always good practice to 
//       to initialize all members of your class during construction (preferably in the
//       initialization list).
//
// Note: This was defined this way so that the C++ is backward compatible with C.
//       And obeys the rule of don't do more than you need too (because we want the C++
//       code to be as fast and efficient as possible.


Y::Y(Y const& rhs)
    :X(rhs)              // Copy construct the base
    ,a(rhs.a)            // Copy construct each member using the copy constructor.
    ,b(rhs.b)            // NOTE: The order is explicitly defined
    ,z(rhs.z)            //       as the order of declaration in the class.
{}

Y& operator=(Y const& rhs)
{
    X::operator=(rhs);   // Use base assignment operator
    a  = rhs.a;          // Use the assignment operator on each member.
    b  = rhs.b;          // NOTE: The order is explicitly defined
    z  = rhs.z;          //       as the order of declaration in the class.
    return(*this);
}

Y::~Y()
{
    Your Code first
}
// Not legal code. Trying to show what happens.
  : ~z()
  , ~b() // Does nothing for pointers.
  , ~a() // Does nothing for POD types
  , ~X() ; // Base class destructed last.

#3


4  

Just to expand on Armen Tsirunyan answer here are the signatures for the methods:

以下是这些方法的签名:

// C++03
MyClass();                                     // Default constructor
MyClass(const MyClass& other);                 // Copy constructor
MyClass& operator=(const MyClass& other);      // Copy assignment operator
~MyClass();                                    // Destructor

// C++11 adds two more
MyClass(MyClass&& other) noexcept;             // Move constructor
MyClass& operator=(MyClass&& other) noexcept;  // Move assignment operator

#4


0  

Is that it?

是它吗?

Yes thats it.

是的这是它。

Compiler generates by default

编译器生成默认情况下

  • A default constructor
  • 一个默认的构造函数
  • A copy constructor
  • 一个拷贝构造函数
  • A copy assignment operator
  • 拷贝赋值运算符
  • A destructor
  • 一个析构函数

for a class

为一个类

You can see the default constructor, the copy constructor and the assignment operator being generated by default when you use -ast-dump option of Clang

您可以看到默认构造函数、复制构造函数和在使用- astdump选项时默认生成的赋值操作符。

prasoon@prasoon-desktop ~ $ cat empty.cpp && clang++ -cc1 -ast-dump empty.cpp
class empty
{};

int main()
{
   empty e;
   empty e2 = e;
   {
     empty e3;
     e3 = e;
   }

}
typedef char *__builtin_va_list;
class empty {
    class empty;
    inline empty() throw(); //default c-tor
    //copy c-tor
    inline empty(empty const &) throw() (CompoundStmt 0xa0b1050 <empty.cpp:1:7>)

    //assignment operator   
    inline empty &operator=(empty const &) throw() (CompoundStmt 0xa0b1590 <empty.cpp:1:7>
  (ReturnStmt 0xa0b1578 <col:7>
    (UnaryOperator 0xa0b1558 <col:7> 'class empty' prefix '*'
      (CXXThisExpr 0xa0b1538 <col:7> 'class empty *' this))))


};

#5


0  

Default methods assigned by compiler for a empty class:

编译器为空类分配的默认方法:

http://cplusplusinterviews.blogspot.sg/2015/04/compiler-default-methods.html

http://cplusplusinterviews.blogspot.sg/2015/04/compiler-default-methods.html