2012-01-24 5 views
4

Почему B(B&) ctor называется, а не B(const B&), при строительстве объекта b1?Почему первый конструктор копирования вызывается в коде ниже?

#include <iostream> 
using namespace std; 

struct B 
{ 
    int i; 
    B() : i(2) { } 
    B(B& x) : i(x.i) { cout << "Copy constructor B(B&), i = " << i << endl; } 
    B(const B& x) : i(x.i) { cout << "Copy constructor B(const B&), i = " << i << endl; } 
}; 

int main() 
{ 
    B b; 
    B b1(b); 
} 
+1

потому что b не const? –

ответ

2

13.3.3.2/3 говорит

Два неявное преобразование последовательности одной и той же формы являются неразличимыми последовательностями конверсии, если только не применяется следующих правил:

- стандартная последовательность преобразования S1 является лучше, чем последовательность преобразования последовательности стандартного преобразования S2, если:

S1 и S2 являются ссылочными привязки (8.5.3), а также типы, к которым относятся ссылки являются одинаковыми типа за исключением квалификаторов cv верхнего уровня, и тип, к которому относится ссылка, инициализированная ссылкой S2, - это больше, чем тип, к которому относится ссылка, инициализированная S1. [Пример:

int f(const int &); 
int f(int &); 
... 
int i; 
int j = f(i); // calls f(int&) 

В вашем случае, так как аргумент неконстантный, то неконстантная версия копии с-тор выбрана потому, что это лучший матч.

+0

Отличный ответ. Поздравления ! – Ayrosa

5

Потому что b не const. Поэтому он идеально подходит для первого экземпляра ctor, так что это то, что использует компилятор.

+0

Не могли бы вы дать некоторые рекомендации? – Belloc

6

Это потому, что применяется разрешение перегрузки, и так как аргумент в конструктор b1 является b и b случается Неконстантным-значение, то выбирается конструктор принимает неконстантную lvlalue. И это первый. Интересно, что оба являются конструкторами копирования, но ваш код будет равным действительным только с последним.

+0

Любые ссылки? – Belloc

+1

целая статья 12.8 в ИСО/МЭК 14882 касается конструкторов копирования; anythying конкретных вас интересует? Что касается перегрузки, это целая глава 13. И это довольно сложно. – bronekk

+0

... Плюс куча статей, касающихся разрешения перегрузки ... Что вас беспокоит? –

1

Попробуйте это:

int main() { 
    const B b; 
    B b1(b); 
} 

Кроме того, это трудное решение Wheter вы должны использовать сопзЬ или нет;)