Требуется ли копия CTOR, даже если она никогда не вызывается? - PullRequest
8 голосов
/ 10 июня 2011

рассмотрим следующее:

class X {
public:
    X(int i) { cout << "X(int i)" << endl; }
    X(const X& x) { cout << "X(const X& x)" << endl; }
};

void main() {
    X x1(1);
    X x2 = X(1);
    X x3 = (X)1;
}

выполнение этого кода приводит к таким выводам:

X(int i)
X(int i)
X(int i)

Я думал, что все вышеперечисленные три оператора эквивалентны, так как копия CTOR никогда не вызывается,Однако при изменении X копии CTOR на частную:

class X {
public:
    X(int i) { cout << "X(int i)" << endl; }
private:
    X(const X& x) { cout << "X(const X& x)" << endl; }
};

Не удастся скомпилировать (в Visual Studio 2010) с этой ошибкой:

cannot access private member declared in class 'X'

Так что, похоже,Копия CTOR как-то задействована, хотя я не совсем понимаю, как.

Спасибо

Ответы [ 4 ]

5 голосов
/ 10 июня 2011
X x1(1);
X x2 = X(1);
X x3 = (X)1;

Причина в том, что все они не совсем эквивалентны.

Первый - прямая инициализация , а второй и третий - копирование-инициализация .Для инициализации копирования, конструктор копирования должен быть общедоступным, иначе компилятор выдаст ошибку.

Теперь возникает вопрос: если 2-й и 3-й требует, чтобы copy-ctor был общедоступным, то почему следующий вывод:

X(int i)
X(int i)
X(int i)

Это, безусловно, говорит о том, что copy-ctor никогда не вызывается, что является правдой.Компилятор просто исключил вызов copy-ctor.Согласно §8.5 / 14, в таких случаях компилятору разрешается исключать необходимость вызывать copy-constructor.Вот почему вы не видите, что вызывается copy-ctor.

Немного изнутри: во 2-м и 3-м случае сначала создается временный объект, вызывая X(int i), затем этот временный объект должен был быть переданкопировать-ctor для копирования-инициализации объявляемого объекта.Но компилятор оптимизирует этот шаг, исключая вызов copy-ctor.

3 голосов
/ 10 июня 2011

X x2 = ... вызывает конструктор копирования (даже если компилятор оптимизирует его позже). Таким образом, он все еще должен быть доступен.

0 голосов
/ 10 июня 2011

Ist объект использует parrametrized конструктор, как вы его знаете, а все остальные используют конструктор копирования. то есть почему, когда вы делаете это, происходит нарушение частного доступа. Два других объекта используют конструктор копирования.

Это способ использования конструктора копирования.

0 голосов
/ 10 июня 2011
  1. Это:

    X x3 = (X) 1; выполняется в стиле c из int в объект типа X

  2. Это копирование:

    X x2 = X (1);

оптимизирован, но компилятору по-прежнему нужен доступ к конструктору копирования.

...