c ++ приведение базового класса в беспорядок производного класса - PullRequest
11 голосов
/ 08 января 2011

Если бы я должен был создать базовый класс с именем base и производные классы с именем derived_1, derived_2 и т. Д. ... Я использую коллекцию экземпляров базового класса, тогда, когда я получил элемент и попытался используя его, я обнаружил бы, что C ++ думает, что это тип базового класса, вероятно, потому что я получил его из std::vector из base. Что является проблемой, когда я хочу использовать функции, которые существуют только для определенного производного класса, тип которого я знал, что этот объект был, когда я помещал его в вектор.

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

(derived_3)obj_to_be_fixed;

И вспомнил, что это указатель. После некоторых настроек это теперь сработало.

*((derived_3*)&obj_to_be_fixed);

Это правильно или есть, например, функция abc_cast(), которая делает это с меньшим количеством беспорядка?

редактирование:

Мне пришлось расширить это на другой вопрос, там показаны полные решения. stackoverflow.com ... вопрос о причинах и типах ошибок и очистки

Ответы [ 4 ]

19 голосов
/ 08 января 2011

Если вы храните ваши объекты в std::vector<base>, просто невозможно вернуться к производному классу.Это связано с тем, что производная часть была разрезана при хранении в экземпляре базового класса (в конце концов, ваш вектор содержит копии ваших данных, поэтому он успешно копирует только базовую часть ваших объектов), что делает сохраненный объект истинным экземпляромбазовый класс, вместо производного класса, используемого в качестве базового класса.

Если вы хотите хранить полиморфные объекты в векторе, сделайте его std::vector<base*> (или какой-нибудь умный указатель для базы, но не для самой базы)и используйте dynamic_cast<derived_3*>, чтобы привести его к правильному типу (или static_cast, если его производительность чувствительна, и вы достаточно уверены, что пытаетесь привести к правильному типу (в этом случае ужасные вещи произойдут, если вы ошибаетесь,так что будьте осторожны)).

5 голосов
/ 08 января 2011

Если вы используете vector из base, тогда все ваши экземпляры являются base экземплярами, а не производными экземплярами.

Если вы попытаетесь вставить производный экземпляр, объект будет нарезан . Вставка в vector всегда включает в себя copy , а тип цели определяется типом объекта, который содержит вектор. vector не может содержать объекты разных типов.

1 голос
/ 08 января 2011

В большинстве случаев вам не нужно этого делать.Тщательно разработанная иерархия классов может справиться с этим путем полиморфизма (т. Е. Виртуальных функций).

Если вам действительно нужно привести к производному типу, используйте оператор dynamic_cast.

0 голосов
/ 08 января 2011

То, что вы пытаетесь сделать, даже отдаленно невозможно.Если объекты, хранящиеся в вашем контейнере, имеют тип base, то они base, точка.Они не являются derived объектами, они никогда не станут derived объектами, и их нельзя использовать в качестве derived объектов независимо от того, что вы делаете.

Ваше приведение через указатели - не что иное, как взлом, который переосмысливаетпамять занята base объектом как derived объектом.Это совершенно бессмысленно и может «работать» только случайно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...