LINUX.ORG.RU

gcc и копирующий конструктор.


0

0

Имеем код:

 #include <iostream>

class C1
{
        int i;

        public:
        C1(int I) {i = I; std::cout << "C1 int constructor" <<std::endl;}
        C1(const C1& c) {i = c.i; std::cout << "C1 copy construcror" << std::endl;}
        C1& operator=(const C1& c ) {i = c.i; std::cout <<"C1 operator =" << std::endl; return *this;}
        ~C1() {std::cout << "C1 destructor " << i << std::endl; }
};


int main()
{
        C1 c1 = C1(2);
}

который выдает:

% g++ -std=c++98 -pedantic -Wall -Wextra c++test15.cc
% ./a.out
C1 int constructor
C1 destructor 2

Заметьте при инициализации переменной с1 в main вызывается «C1 int constructor» а о копирующем конструкторе не слова. теперь меняем код:

...
      explicit C1(const C1& c) {i = c.i; std::cout << "C1 copy construcror" << std::endl;}
...

В итоге имеем:

% g++ -std=c++98 -pedantic -Wall -Wextra c++test15.cc
c++test15.cc: In function 'int main()':
c++test15.cc:17: error: no matching function for call to 'C1::C1(C1)'
c++test15.cc:8: note: candidates are: C1::C1(int)

Что называется опаньки! Да типа по правилам языка при инициализации вызывается копирующий конструктор, а он закрыт вот и не собралось. Но если я при инициализации хочу в копирующем конструкторе кое что лишнее сделать то «хрен вам молодые люди», нужный конструктор не вызовется! Вот такая прикольная фича в компиляторе...

ЕМНИП это прикольная фича в стандарте, компилятор в праве так делать.

Begemoth ★★★★★
()

Стандарт 12.8 / 15 - Оптимизация временных объектов. Компилятор прав в данном случае.

Kristi
()

>Но если я при инициализации хочу в копирующем конструкторе кое что лишнее сделать то «хрен вам молодые люди», нужный конструктор не вызовется!
Зачем?

Booster ★★
()

Простите меня если я заблуждаюсь, но я думал, что

 C1 c1 = C1(2); 

альтернативная форма записи вызова конструктора, конструктор копирования ни при чем. Это как инициализация значением по умолчанию в шаблонах

T a = T(), работает с примитивными типами и классами.

vertexua ★★★★★
()
Ответ на: комментарий от vertexua

Конструктор копирования вызывается если:

1. Объект возвращает значение
2. Объект передается по значению в качестве аргумента
3. Объект конструируется на основе другого объекта того же класса
4. Компилятор генерирует временный объект

Здесь как раз третий случай

m0rph ★★★★★
()
Ответ на: комментарий от anonymous

В смысле, с чего бы «Здесь как раз третий случай»?

anonymous
()
Ответ на: комментарий от m0rph

Вы же видите в первом примере что вызывается один конструктор и один деструктор. Это означает, что это альтернативная форма записи конструктора.

MyClass m(1,2,3);

эквивалентно

MyClass m = MyClass(1,2,3);

Но не эквивалентно

MyClass a(1,2,3);

MyClass m = a;

так как именно в этом случае запускается конструктор копирования

vertexua ★★★★★
()
Ответ на: комментарий от vertexua

Действительно, сейчас проверил и признаю свою ошибку.

m0rph ★★★★★
()
Ответ на: комментарий от vertexua

>альтернативная форма записи конструктора
при этом требуется, чтобы конструктор копирования был доступен, и компилятор вправе его вызвать

gavv
()

>Но если я при инициализации хочу в копирующем конструкторе кое что лишнее сделать
расхоти! и поскорее, пока твой начальник это не увидел!

xydo ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.