Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
rikimaru2013
C++ Game Dev
2380 / 1074 / 235
Регистрация: 30.11.2013
Сообщений: 3,570
#1

Оператор присваивания по умолчанию - C++

25.11.2014, 15:36. Просмотров 512. Ответов 15
Метки нет (Все метки)

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
using namespace std;
 
class Foo
{
private:
    int var;
        //int var = 17;
public:
    /*Foo& operator=(const Foo& right)
    {
        
        return *this;
    }*/
};
void main()
{
    Foo a;
    Foo b;
    a = b;
}
Добрый день, не могу найти где почитать почему по умолчанию оператор присваивания не копирует "мусор" побитово.
Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
MrGluck
Ворчун
Эксперт CЭксперт С++
6677 / 3858 / 511
Регистрация: 29.11.2010
Сообщений: 10,217
25.11.2014, 15:45     Оператор присваивания по умолчанию #2
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
using namespace std;
 
class Foo
{
private:
    int var;
        //int var = 17;
public:
    Foo(int x) : var(x) {}
    int getVar() const { return var; }
    /*Foo& operator=(const Foo& right)
    {
 
        return *this;
    }*/
};
int main()
{
    Foo a(1);
    Foo b(2);
    a = b;
    std::cout << a.getVar();
}
не понял, в чём проблема?
Что есть мусор?
Ilot
Модератор
Эксперт С++
1785 / 1160 / 225
Регистрация: 16.05.2013
Сообщений: 3,056
Записей в блоге: 5
Завершенные тесты: 1
25.11.2014, 15:47     Оператор присваивания по умолчанию #3
С чего вы так решили? Все нормально копируется.
MrGluck, мусор - без инициализации:
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
class Foo {
public:
    int var;
};
int main() {
    Foo a;
    Foo b;
    a = b;
    std::cout << a.var << ' ' << b.var << std::endl;
    return 0;
}
rikimaru2013
C++ Game Dev
2380 / 1074 / 235
Регистрация: 30.11.2013
Сообщений: 3,570
25.11.2014, 15:53  [ТС]     Оператор присваивания по умолчанию #4
Оператор присваивания по умолчанию
VS 2013: ошибка компиляции.

Хочу понять согласно какой строке стандарта. Или это VS защищает меня от "неловких ситуаций в дальнейшем", но почему не Warning, а ошибка компиляции.
MrGluck
Ворчун
Эксперт CЭксперт С++
6677 / 3858 / 511
Регистрация: 29.11.2010
Сообщений: 10,217
25.11.2014, 15:58     Оператор присваивания по умолчанию #5
Я вначале тоже попробовал без инициализации приравнять, также всё ок.

Я, возможно, кэповскую вещь скажу, но компилятор когда не находит явно объявленного оператор присваиваний делает что-то типа этого:
C++
1
2
3
4
5
6
7
8
9
Foo& Foo::operator=(const Foo &rhs)
{
    if (this != &rhs)
    {
        // для каждого поля класса Foo
        this->поле = rhs->поле
        // или же this->поле.operator=(rhs->поле)
    }
}
Поэтому, когда в классе есть указатели на динамич. память, требуется оператор определить явно т.к. иначе он сделает
указатель lhs = указатель rhs. В итоге, два указателя будут указывать на одну и ту же область памяти и есть риск, что произойдёт ошибка с попыткой повторного освобождения памяти.

Добавлено через 1 минуту
Наверняка, стоит флаг /WX
Свойства проекта > C/C++ > Treat Warnings As Errors.
Ilot
Модератор
Эксперт С++
1785 / 1160 / 225
Регистрация: 16.05.2013
Сообщений: 3,056
Записей в блоге: 5
Завершенные тесты: 1
25.11.2014, 15:58     Оператор присваивания по умолчанию #6
Сообщение было отмечено автором темы, экспертом или модератором как ответ
rikimaru2013, потому, что MS слишком много на себя берет.
MrGluck
Ворчун
Эксперт CЭксперт С++
6677 / 3858 / 511
Регистрация: 29.11.2010
Сообщений: 10,217
25.11.2014, 15:59     Оператор присваивания по умолчанию #7
Цитата Сообщение от Ilot Посмотреть сообщение
rikimaru2013, потому, что MS слишком много на себя берет.
это обычный варнинг
http://msdn.microsoft.com/ru-ru/library/axhfhh6x.aspx
rikimaru2013
C++ Game Dev
2380 / 1074 / 235
Регистрация: 30.11.2013
Сообщений: 3,570
25.11.2014, 16:05  [ТС]     Оператор присваивания по умолчанию #8
Цитата Сообщение от MrGluck Посмотреть сообщение
Наверняка, стоит флаг /WX
Свойства проекта > C/C++ > Treat Warnings As Errors.
Проверил c:
Yes (/WX)
No (/WX-)
стоит по умол No (/WX-)

Добавлено через 3 минуты
Всем спасибо за помощь, соглашусь с Ilot, в стандарте ничего не нашёл про это, поэтому это MS решило помоч нам. И никак не отключить ошибку компиляции )))
MrGluck
Ворчун
Эксперт CЭксперт С++
6677 / 3858 / 511
Регистрация: 29.11.2010
Сообщений: 10,217
25.11.2014, 16:28     Оператор присваивания по умолчанию #9
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
И никак не отключить ошибку компиляции )))
Сейчас посмотрел - да, для свойств классов они генерируют ошибку компиляции. Но можно отключить в Exceptions в Native Run-Time Check(сейчас найду как до этого меню дойти) и возможно ещё кое-где. Напишу инструкцию попозже.

Добавлено через 31 секунду
Но это поведение точно не по стандарту и является инициативой MS. Ilot прав.

Код достаточно обрамить макросами
C++
1
2
#pragma runtime_checks( "", s )
#pragma runtime_checks( "", restore )
Добавлено через 4 минуты
А ещё лучше - правой клавишей по проекту > Properties > C/C++ > Code Generation > Basic Runtime Checks > выбрать Stack Frames (/RTCs)

Добавлено через 1 минуту
http://msdn.microsoft.com/en-us/library/6kasb93x.aspx
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
3620 / 1895 / 502
Регистрация: 18.10.2014
Сообщений: 3,459
25.11.2014, 17:39     Оператор присваивания по умолчанию #10
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
не копирует "мусор" побитово.
В С++ копирующий оператор присваивания, определенный компилятором, никогда ничего не копировал "побитово". Концепции "побитового" копирования на уровне ядра языка в С++ просто нет.

Цитата Сообщение от rikimaru2013 Посмотреть сообщение
Или это VS защищает меня от "неловких ситуаций в дальнейшем", но почему не Warning, а ошибка компиляции.
Это warning, а не ошибка компиляции. А erorr он стал потому, что где-то в настройках проекта вы специально попросили, чтобы этот warning стал erorr. Вопрос лишь - где.

Цитата Сообщение от MrGluck Посмотреть сообщение
Код достаточно обрамить макросами
C++
1
2
#pragma runtime_checks( "", s )
#pragma runtime_checks( "", restore )
Эти установки управляют проверками времени выполнения, а в данном случае речь идет об ошибке времени компиляции.

Цитата Сообщение от rikimaru2013 Посмотреть сообщение
Хочу понять согласно какой строке стандарта.
Строка стандарта тут очень простая. Чтение значения неинициализированного объекта приводит к неопределенному поведению.

4.1 Lvalue-to-rvalue conversion [conv.lval]
1 A glvalue (3.10) of a non-function, non-array type T can be converted to a prvalue.53 If T is an incomplete type, a program that necessitates this conversion is ill-formed. If the object to which the glvalue refers is not an object of type T and is not an object of a type derived from T, or if the object is uninitialized, a program that necessitates this conversion has undefined behavior.
Проявления неопредленного поведения не ограничены временем выполнения, а могут выражаться также и в в отказе компилятора компилировать программу.

1.3.24 [defns.undefined] undefined behavior
behavior for which this International Standard imposes no requirements
[ Note: Undefined behavior may be expected when this International Standard omits any explicit definition of behavior or when a program uses an erroneous construct or erroneous data. Permissible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message). Many erroneous program constructs do not engender undefined behavior; they are required to be diagnosed.
—end note ]
Считайте, что именно это и произошло в вашем случае. Так что формально тут придраться не к чему. А фактически - вопрос в том, как вы умудрились превратить warning C4700 в error. Смотрите в настройки проекта.
MrGluck
Ворчун
Эксперт CЭксперт С++
6677 / 3858 / 511
Регистрация: 29.11.2010
Сообщений: 10,217
25.11.2014, 17:49     Оператор присваивания по умолчанию #11
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
А фактически - вопрос в том, как вы умудрились превратить warning C4700 в error. Смотрите в настройки проекта.
Цитата Сообщение от MrGluck Посмотреть сообщение
Сейчас посмотрел - да, для свойств классов они генерируют ошибку компиляции.
У них такое идёт независимо от флага Treat Warnings As Errors.

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Эти установки управляют проверками времени выполнения, а в данном случае речь идет об ошибке времени компиляции.
sdl проверки ещё выключить. Просто даже при их выключении он в рантайме пробует проверить.
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
3620 / 1895 / 502
Регистрация: 18.10.2014
Сообщений: 3,459
25.11.2014, 18:32     Оператор присваивания по умолчанию #12
Цитата Сообщение от MrGluck Посмотреть сообщение
У них такое идёт независимо от флага Treat Warnings As Errors.
Это у кого - "у них"? Я только что попытался скомпилировать этот же код VS 2013 Update 4. Никакого error я не получил. Только warning C4700.

Цитата Сообщение от MrGluck Посмотреть сообщение
sdl проверки ещё выключить.
В моем случае я попробовал включить SDL проверки. Но warning остался warning-ом. Так что что именно у ТС там такое еще включено (если не warnings as errors) я не знаю.

Добавлено через 12 минут
ТС надо показать нам командную строку cl.exe из свойств проекта. Там все должно быть видно.
rikimaru2013
C++ Game Dev
2380 / 1074 / 235
Регистрация: 30.11.2013
Сообщений: 3,570
25.11.2014, 18:48  [ТС]     Оператор присваивания по умолчанию #13
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
ТС надо показать нам командную строку cl.exe из свойств проекта. Там все должно быть видно.
C++
1
/GS /analyze- /W3 /Zc:wchar_t /ZI /Gm /Od /sdl /Fd"Debug\vc120.pdb" /fp:precise /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_LIB" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /RTCs /Gd /Oy- /MDd /Fa"Debug\" /EHsc /nologo /Fo"Debug\" /Fp"Debug\TESTING_ONLY.pch"
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
3620 / 1895 / 502
Регистрация: 18.10.2014
Сообщений: 3,459
25.11.2014, 21:26     Оператор присваивания по умолчанию #14
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
...
Дело в SDL.

Происходит вот что: при включенном SDL этот warning превращается в error, но только в Win32 конфигурациях. В x64 кофигурациях включение SDL такого эффекта не имеет: warning остается warning. Я у себя пробовал именно в x64 конфигурации, поэтому и не заметил такого эффекта от SDL.
hoggy
6171 / 2537 / 444
Регистрация: 15.11.2014
Сообщений: 5,619
Завершенные тесты: 1
25.11.2014, 23:16     Оператор присваивания по умолчанию #15
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
Добрый день, не могу найти где почитать почему по умолчанию оператор присваивания не копирует "мусор" побитово.
Дефолтный - почленно.

Грубо говоря, для каждого члена класса вызывается operator=
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.11.2014, 23:37     Оператор присваивания по умолчанию
Еще ссылки по теме:

Оператор присваивания C++
Оператор присваивания C++
C++ Некорректно работает оператор присваивания
Перегруженный оператор присваивания C++

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

Или воспользуйтесь поиском по форуму:
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
3620 / 1895 / 502
Регистрация: 18.10.2014
Сообщений: 3,459
25.11.2014, 23:37     Оператор присваивания по умолчанию #16
Цитата Сообщение от hoggy Посмотреть сообщение
Дефолтный - почленно.
Вот именно - почленно. Но ни разу не "побитово".
Yandex
Объявления
25.11.2014, 23:37     Оператор присваивания по умолчанию
Ответ Создать тему
Опции темы

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