Почему инициализация копирования такая, какая она есть? Зачем нужен конструктор копирования?

Возможный дубликат:
Какова причина того, что копирование и прямая инициализация ведут себя по-разному?

И под инициализацией копирования я имею в виду так:

struct MyStruct
{
    MyStruct(int) {}
    MyStruct(const MyStruct&) {}
};

MyStruct s = 5; // needs *both* the int and copy constructor

Несмотря на долгие годы программирования на C++, я так и не понял, что для приведенного выше кода требуется конструктор копирования (благодаря jogojapan). Времена всегда были исключены, и я даже не знал, что они вообще существуют (по крайней мере, на поверхностном уровне, несмотря на то, что они были оптимизированы), пока на меня не указали.

После приличного количества поисков в Google, я понимаю, как это работает. Мой вопрос: почему это так?

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

Без приличного объяснения того, почему вещи такие, какие они есть, я просто рассматриваю это как раздражающий артефакт, но я бы предпочел не быть в неведении, если есть что-то важное, что я упускаю.

1 ответ

Решение

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

int a = 4;
int a = int(4);
int a(4);

все эти вызовы неоднозначны, все они установлены равными 4. Причиной для конструктора копирования в случае целого числа является удобство, представьте, что типы данных C++ без этого

int a(foo(b,r)); //a little messy for a variable declaration
int a = foo(b,r) //ok, cleaner

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

#include <iostream>
using std::cout;
using std::endl;
class complexNumbers {
  double real, img;
public:
  complexNumbers() : real(0), img(0) { }
  complexNumbers(const complexNumbers& c) { real = c.real; img = c.img; }
  explicit complexNumbers( double r, double i = 0.0) { real = r; img = i; }
  friend void display(complexNumbers cx);
};
void display(complexNumbers cx){
  cout<<&quot;Real Part: &quot;<<cx.real<<&quot; Imag Part: &quot;<<cx.img<<endl;
}
int main() {
  complexNumbers one(1);
  display(one);
  complexNumbers two =2;
  display(200);
  return 0;
}
Другие вопросы по тегам