Почему этот код может исключить копию?
Возможные дубликаты:
механизм вызова конструктора
Почему ошибочно использовать пустой набор скобок для вызова конструктора без аргументов?
Почему этот код может исключить все копии 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++ позволяет это делать. Вы можете ввести определение переменной с помощью дополнительных скобок.