Почему этот код может исключить копию?

Возможные дубликаты:
механизм вызова конструктора
Почему ошибочно использовать пустой набор скобок для вызова конструктора без аргументов?

Почему этот код может исключить все копии A?

#include <iostream>

class A
{
public:
  A() {}
  A(const A&) { std::cout << "Copy" << std::endl; }
};

class B
{
public:
  B(const A& a_) : a(a_) {}
private:
  A a;
};

int main()
{
  B b(A());
}

Этот код, очевидно, не делает копии Aи ничего не выводит под gcc 3.4 в ideone.

3 ответа

Решение

Проблема не в копировании, а в значении декларации:

B b(A());
// To get it working the way you expect [1]
B b = B(A());
// Or the slightly more obtuse.
B b((A()));

К компилятору относится объявление функции. Гугл / поиск ТАК для самого неприятного разбора. Больше в C++ FAQ Lite, включая обходные пути.


[1]: Это не совсем то же самое, поскольку это требует неявного преобразования из A в B, Если B был определен как:

class B {
  A a;
public:
  explicit B(const A& a_) : a(a_) {}
};

Тогда это не будет альтернативой.

B b(A());

Вы думаете, что это объявляет переменную? Нет.

Объявляет функцию b чей тип возврата B и принимает параметр типа A (*)(),

Смотрите эту тему:


Так что если вы хотите объявить переменную, поставьте дополнительные скобки вокруг A() как:

B b((A())); //it declares an object

Использование:

B b((A()));

ваша строка является объявлением функции. К сожалению, C допускает объявления функций внутри функций (что, кстати, мне кажется, довольно бесполезно), поэтому по причинам обратной совместимости C++ позволяет это делать. Вы можете ввести определение переменной с помощью дополнительных скобок.

Другие вопросы по тегам