Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: преобразование типа и классы
Форум на CrossPlatform.RU > Разработка > С\С++
voipp
Значит есть класс CTable от него наследуется CMatrix а от него SLAU.наследование открытое. в CTable определен operator=(const CTable& table). Строчки вида
CTable A;
SLAU B;
B=A;
без ошибок компилируются.А вот строчки вида
SLAU A,B;
CMatrix A1,A2;
A=(B+A1*A2);
вводят компилятор в недоумение(операции сложения и умножения выполняются без ошибок).Вот что он пишет: не найден оператор= принимающий правый аргумент типа CMatrix
Теперь в недоумении я.Почему это происходит и как это исправить?
kwisp
voipp,
по-моему все верно происходит нет же оператора = для CMatrix!
вот если заменить тут
SLAU A,B;
CMatrix A1,A2;
A=(B+A1*A2);

CMatrix на CTable
соберётся думаю.
может надо написать оперетор = для CMatrix.
voipp
строчки такого вида будут без ошибок:
CMatrix A;
SLAU B;
B=A;


Litkevich Yuriy
Цитата(voipp @ 5.4.2010, 3:53) *
строчки такого вида будут без ошибок:
CMatrix A;
SLAU B;
B=A;
а наоборот:
A=B;
?
voipp
Цитата(Litkevich Yuriy @ 5.4.2010, 8:20) *
Цитата(voipp @ 5.4.2010, 3:53) *
строчки такого вида будут без ошибок:
CMatrix A;
SLAU B;
B=A;
а наоборот:
A=B;
?

Я перепутал.Как раз строки А=В без ошибок а строки В=А с ошибками
ViGOur
voipp, добавь в класс SLAU конструктор копий такого вида: SLAU(const CTable&){} и все будет компилиться!
И подумай, почему он нужен! ;)
kwisp
ViGOur,
давайте обсудим эту тему.
по-моему конструктор копий понадобился если бы было так:
CMatrix A;
SLAU B=A;


а у него:
CMatrix A;
SLAU B;
B=A;


по-моему оператор = принимающий CMatrix нужен.
он же переопределил оператор = в родительском классе теперь , это на его совести.

или я ошибаюсь? поправьте.

ViGOur
Как вариант можно и оператор присваивания: SLAU &operator=(const CTable&){}.
Влад
Вообще-то, "по правильному" и operator=, и конструктор копирования должны принимать в качестве аргумента (константную ссылку на) объект своего же класса. Все преобразования должны осуществляться явно соответствующими операторами, причем, если это конструкторы - то стоит объявить их explicit во избежание выполнения не предусмотренных программистом преобразований.
ViGOur
Ну почему же!
Что не правильно в том, что оператор присваивания класса Integer будет принимать в качестве параметра int?

Добавлено:

Или если взять пример:

class Животное{...};
class Лошадь: public Животное{...};

Почему не правильно: Лошадь::operator=( Животное&) ?
Лошадь это же животное и почему ей нельзя присвоить все свойства присущие животному, того или иного возраста или пола?

з.ы. я знаю, что это не правильно.
Просто хочу услышать почему, так как уже не помню почему! :lol:
AD
Да все очень просто. Лучше не делать таких вот операторов из-за неявного преобразования типов. о вреде неявного преобразования написано очень много. Думаю, сможешь найти! :)
Iron Bug
да, я тоже стараюсь избегать неявного преобразования типов.
к тому же, тут компилятор иногда может оказать "медвежью услугу": у мелкософта, к примеру, он сам генерит пустые конструкторы и конструкторы копий по умолчанию. а это, на самом деле, потенциальная дыра. я уже один раз напарывалась на это. уж если нужно преобразование, то его нужно указывать явно. а если оно ещё и сложное - то самому прописывать это преобразование, не надеясь на то, что может придумать компилятор.
ViGOur
Цитата(Iron Bug @ 5.4.2010, 22:05) *
у мелкософта, к примеру, он сам генерит пустые конструкторы и конструкторы копий по умолчанию.
Ну вообще-то это кажется по стандарту. :)
kwisp
Цитата(ViGOur @ 5.4.2010, 22:54) *
Ну вообще-то это кажется по стандарту. :)

в том то и дело как я понял. если ты не пишешь ничего руками ни конструктор копий ни конструктор по умолчанию, то это за тебя сделает компилятор, однако если ты хотя бы в одном классе родительском переопределишь конструтор копий -- компилятор умывает руки, дальше делай всё сам.
я так понимаю.
Влад
Не совсем так. Дефолтный конструктор, конструктор копирования, оператор = и деструктор относятся к специальным член-функциям.
Дефолтный конструктор генерируется компилятором автоматически, если не указан явно ни один пользовательский конструктор. Как правило, такой дефолтный конструктор пустой и успешно оптимизируется компилятором. Однако, для всех баз и членов вызываются их дефолтные конструкторы, если таковые существуют, иначе генерируется ошибка компиляции. Для баз - в порядке их объявления в списке наследования, для членов - в порядке их объявления.
Конструктор копирования не наследуется. Если не указан явно пользовательский конструктор копирования, то генерируется дефолтный конструктор копирования, который тупо почленно копирует все базы и члены класса. Порядок копирования тот же.
То же самое верно и для оператора =. Если не указан явно пользовательский оператор назначения (присваивания), то генерируется дефолтный оператор =, который тупо вызывает операторы = для всех баз и членов. Порядок тот же.
Тот же самый принцип действует и для деструкторов, с одним отличием: деструкторы всегда вызываются в порядке, обратном вызовам конструкторов.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.