Форум программистов, компьютерный форум, киберфорум
Наши страницы

C++

Войти
Регистрация
Восстановить пароль
 
Tulosba
:)
Эксперт С++
4397 / 3233 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
#1

Доступность копирующего конструктора - C++

18.11.2013, 18:07. Просмотров 431. Ответов 6
Метки нет (Все метки)

Всем привет.

Не так давно в одной из тем была упомянута статья Герба Саттера Variable Initialization – or Is It?.

По статье остался не понятен момент в п.1 при описании кода (f), (g). В частности абзац:

Note that I said “conceptually” a few times above. That’s because practically compilers are allowed to, and routinely do, optimize away the temporary and, if an implicit conversion is available, convert (f) to (d), thus optimizing away the extra move operation. However, even when the compiler does this, the widget copy constructor must still be accessible, even if is not called—the copy constructor’s side effects may or may not happen, that’s all.
Правильно ли я понял, что для случая:
C++
1
widget w = x;
даже когда компилятор может убрать лишние вызовы конструкторов, копирующий конструктор (даже если он не вызывается) должен быть доступен?

Если я понял правильно, то это не совсем соответствует действительности:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
using namespace std;
 
class C
{
public:    
    C() { cout << "C()" << endl; }
    C( int ) { cout << "implicit C(int)" << endl; }
    C( C&& ) { cout << "C(C&&)" << endl; }
    C& operator= ( const C& ) { cout << "operator=" << endl; return *this; }
    //C( const C& ) { cout << "C(const C&)" << endl; }
private:
    C( const C& ) = delete; 
    //C( C&& ) = delete;
};
 
int main() {
    C c1 = 10;
    return 0;
}
Вызывает только один конструктор с целым аргументом:
http://coliru.stacked-crooked.com/a/07558605af3d97b0

Добавляем опцию --no-elide-constructors и получаем еще вызов конструктора перемещения:
http://coliru.stacked-crooked.com/a/ab8813cbab372651

И если теперь убрать конструктор перемещения:
C++
1
C( C&& ) = delete;
, то будет ошибка:
http://coliru.stacked-crooked.com/a/00751bae83617dec
use of deleted function 'C::C(C&&)'
Ну и если снова убрать --no-elide-constructors получим ту же ошибку:
http://coliru.stacked-crooked.com/a/235703e12a3039fd

Т.е. получается, что Саттер вроде как прав, но речь должна идти о конструкторе перемещения, а не копирования.

Поправьте меня, если я не прав.

Заранее спасибо.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
18.11.2013, 18:07
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Доступность копирующего конструктора (C++):

realloc и вызов конструктора - C++
здраствуйте! мне препод сказал, что можно выделить память оператором new, а потом довыделить её с помощью realloc и каким-то образом...

Наследование конструктора от переменного шаблона - C++
В С++ 11 появилась возможность унаследовать конструктора базового класса при помощи конструкции using. class A { public: ...

[template] почему код не компилируется без конструктора - C++
добрый вечер. вопрос поместил прямо в коде. http://rextester.com/AESO94403 #include &lt;iostream&gt; #include &lt;string&gt; #include...

[C++] Взятие адреса конструктора. Физическое время существование объекта. - C++
1. конструктор. class A { int a; public: A():a(555){}; ~A(){}

Почему лучше инициализировать объекты класса во время инициализации конструктора? - C++
Имеется класс Rnd: class Rnd { public: Rnd::Rnd(int x); private: int val; };

Использование конструктора и деструктора - C++ Builder
Добрый вечер подскажите пожалуйста как эту прогу сделать с использованием конструктора и деструктора class Paint : public TForm1 //Создаем...

6
retmas
Жарю без масла
864 / 746 / 168
Регистрация: 13.01.2012
Сообщений: 1,702
18.11.2013, 19:07 #2
думаю он и говорит о конструкторе перемещения в своей статье:
the compiler first implicitly converts x to a temporary widget object, then move-constructs w from that temporary rvalue, using copy construction as “the slow way to move” as a backup if no better move constructor is available
1
Tulosba
:)
Эксперт С++
4397 / 3233 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
18.11.2013, 19:19  [ТС] #3
retmas, похоже в одном абзаце (который привели Вы) Саттер говорит правильно, а в следующем (на котором сделал акцент я) уже почему-то copy constructor. Наверное просто опечатался.
0
retmas
Жарю без масла
864 / 746 / 168
Регистрация: 13.01.2012
Сообщений: 1,702
18.11.2013, 19:26 #4
может быть, но мне думается, что он не опечатался. поясню. вот из вашего отрывка:
thus optimizing away the extra move operation. However, even when the compiler does this, the widget copy constructor must still be accessible, even if is not called
здесь говорится о том, что опускается вызов мув конструктора при оптимизации. но не смотря на это он должен существовать. думаю "copy constructor" здес был не конкретный термин, а обобщение.
может я неверно понял. ваши соображения?
0
ct0r
Игогошка!
1777 / 679 / 42
Регистрация: 19.08.2012
Сообщений: 1,295
Завершенные тесты: 1
18.11.2013, 23:31 #5
then move-constructs w from that temporary rvalue, using copy construction as “the slow way to move” as a backup if no better move constructor is available
thus optimizing away the extra move operation. However, even when the compiler does this, the widget copy constructor must still be accessible, even if is not called—the copy constructor’s side effects may or may not happen, that’s all.
Саттер все правильно сказал. Он ведет речь о случае, в котором у класса нет конструктора перемещения (или он const &&), а в этом случае используется конструктор копирования (так как нет более подходящих перегрузок) как "медленный мув". Поэтому конструктор копирования должен быть определен, даже в случае copy-elision.
1
Tulosba
:)
Эксперт С++
4397 / 3233 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
19.11.2013, 12:15  [ТС] #6
Цитата Сообщение от ct0r Посмотреть сообщение
о случае, в котором у класса нет конструктора перемещения (или он const &&), а в этом случае используется конструктор копирования
ct0r, при наличии copy-конструктора и отсутствии move-конструктора всё равно ошибка:
http://coliru.stacked-crooked.com/a/856c4238243ad836
Если Вы имели в виду что-то другое, пожалуйста, приведите код, подтверждающий Ваши слова.
0
ct0r
Игогошка!
1777 / 679 / 42
Регистрация: 19.08.2012
Сообщений: 1,295
Завершенные тесты: 1
19.11.2013, 13:02 #7
Цитата Сообщение от Tulosba Посмотреть сообщение
при наличии copy-конструктора и отсутствии move-конструктора всё равно ошибка:
По умолчанию мув-конструктора нет (если точнее, то он может быть, но при выполнении целого ряда условий). Потому что иначе старый код может перестать работать. А там ты его объявляешь. delete-функция - это объявленная функция без определения. Поэтому он начинает участвовать в разрешении перегрузки. Надо удалить его нафиг.
http://coliru.stacked-crooked.com/a/8111a130895076c9
2
19.11.2013, 13:02
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.11.2013, 13:02
Привет! Вот еще темы с ответами:

Ошибка при использовании конструктора - C++ Builder
Вот написал часть программы на С++, захотел проверить, но выбило ошибку Unit1.cpp(104): E2294 Structure required on left side of . or .*...

Использование конструктора в потомке класса TThread - C++ Builder
У меня вроде как все работает но есть вопрос читаю про потоки,пробую сам создать вот что получается по статьям в интернете 1ый...

Вызов копирующего конструктора - C++
Помогите привести примеры для всех случаев.. Копирующий конструктор вызывается в следующих случаях: 1)если объект типа type...

1C 8.x Доступность и не доступность флажка на форме - 1С
На форме установлен флажок. При определенных условиях необходимо, что бы он, оставаясь ВИДИМЫМ, становился НЕДОСТУПНЫМ. пытаюсь как-то...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.