2010-10-28 2 views
29

Извините, это может показаться простым, но кто-то спросил меня об этом, и я точно не знаю.Сколько методов по умолчанию имеет класс?

Пустой класс C++ содержит какие функции?

Конструктор, Копировальный конструктор, Назначение, Деструктор?

Это он? Или есть еще?

+0

Его попросили меня в 3 интервью сейчас. – Vbp

ответ

41

В C++ 03 есть 4:

  • Конструктор по умолчанию: Объявлено только если не определено пользователем конструктор . Определяется, когда используется

  • Копировальный конструктор - объявлен только в том случае, если пользователь не объявил его. Определено, если используется

  • оператора копирования-присваивания же, как и выше

  • Destructor же, как и выше

В C++ 11 есть еще два:

  • Переместить конструктор
  • Move присваивание оператор

Также возможно, что компилятор не сможет произвести некоторые из них. Например, если класс содержит, например, ссылку (или что-то еще, что не может быть назначено копией), тогда компилятор не сможет создать для вас оператор присваивания копий.For more information read this

+5

На самом деле в воздухе видно, будет ли конструктор перемещения и оператор назначения перемещения неявным образом объявлены в C++ 0x; есть документы Дейва Абрахама и Бьярна Страуструпа в октябрьской рабочей группе WG21 по этой теме. Существуют опасения, что их неявное объявление может нарушить устаревший код. –

+0

Я думаю, что наличие ссылки в качестве переменной-члена предотвратит генерацию оператора присваивания по умолчанию, а не вызывает проблемы с конструктором копирования. –

+0

@Ben: Да, ты прав, исправляешь. Спасибо :) –

0

Это он?

Да, это так.

компилятор генерирует по умолчанию

  • конструктор по умолчанию
  • Копию конструктор
  • Оператор присваивания копии
  • Деструктор

для класса

Вы можете см. defa Конструктор ии, конструктор копирования и оператор присваивания генерируются по умолчанию при использовании -ast-dump варианта Clang

[email protected] ~ $ 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)))) 


}; 
+0

Я не думаю, что деструктор действительно сгенерирован. – Andrey

+4

Это деструктор по умолчанию, который просто вызывает деструкторы для всех членов. Если это не произошло, все члены будут течь всякий раз, когда поврежден родительский объект. – AshleysBrain

+1

@Ashley На самом деле нет, деструктор ничего не называет. Это делается вне деструктора. –

12

Если я определяю следующий класс

class X 
{}; 

Компилятор будет определять следующие методы:

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. 

Примечание:
конструктор по умолчанию не построен, если ANY конструктор определен ,
Другие методы не построены, если пользователь определяет альтернативу.

Что немного более интересным является реализацией по умолчанию, когда у нас есть члены и основание:

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. 
+1

Определение оператора присваивания, если оно ошибочно, потому что у вас нет оператора return внутри функции, отличной от void. –

+0

И оператор присваивания возвращает постоянную ссылку, значение или пустоту. –

+0

@Let_Me_Be: Нет. Он возвращает ссылку. Попробуйте использовать объект после назначения. –

0

метода по умолчанию, присвоенная компилятором для пустого класса:

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

+1

Хотя эта ссылка может ответить на вопрос, лучше включить здесь основные части ответа и предоставить ссылку для справки. Ответные ссылки могут стать недействительными, если связанная страница изменится. Пожалуйста, посмотрите здесь: [Почему и как удалены некоторые ответы?] (Http://stackoverflow.com/help/deleted-answers) – bummi

3

Просто расширить на Armen Tsirunyan answer приведены подписи для методов:

// 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 
Смежные вопросы