Возврат объекта подкласса из метода родительского класса

Можно ли вернуть экземпляр подкласса объекта внутри метода родительского класса? Что я пытаюсь сделать, так это у меня есть класс Member в качестве родительского и подкласс Voter, и я хочу, чтобы у члена был метод, позволяющий превратить себя в объект избирателя.

это немного назад, чтобы базовый класс знал о подклассах. Как бы то ни было, вы можете показать небольшой пример того, что вы хотите сделать? (см. также минимальный воспроизводимый пример).

463035818_is_not_a_number 31.10.2018 13:55

опишите вашу первоначальную проблему, которую предполагается решить путем возврата объекта подкласса, поскольку он выглядит как XY проблема.

Marek R 31.10.2018 13:57

Любой метод может возвращать любой объявленный вами тип, но вы не можете притворяться, что объект, созданный как «Член» (т. Е. = New Member ()), является подклассом члена; то есть любое статическое / динамическое / переинтерпретированное приведение либо завершится ошибкой, либо приведет к неопределенному поведению

Stephan Lechner 31.10.2018 14:00
0
3
150
2

Ответы 2

Родительский класс не имеет возможности узнать дополнительные методы и члены наследующего класса.

Объект из дочернего класса может быть передан родительскому, но не наоборот.

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

посмотрите на другой ответ. Родителю не нужно знать, какие члены или методы есть у наследующего класса, но он может предоставить метод для возврата экземпляра подкласса.

463035818_is_not_a_number 31.10.2018 14:04

Иногда я использую нечто подобное, обычно это выглядит так:

template<typename MemberType>
class Member
{
public:
    MemberType *asChild() { return static_cast<MemberType*>(this); }
};

class VoterA : public Member<VoterA> {};
class VoterB : public Member<VoterB> {};

Вы можете указать это как угодно, например, переопределить operator*, чтобы разыменование Member выдавало его как заданный тип шаблона. Типичное использование, учтите:

class Elections
{
public:
    void vote(VoterA obj);
    void vote(VoterB obj);
};

Вы также можете сделать так, чтобы элемент проводил голосование:

template<typename MemberType>
class Member
{
public:
    Member(Voter *voter) : mVoter(voter) {}

    void vote()
    {
        mVoter->vote(*static_cast<MemberType*>(this));
    } 

private:
    Voter *mVoter = nullptr;
};

из вопроса не совсем понятно, хочет ли OP литье (ваш ответ) или какое-то преобразование (каким-то образом создавая новый Voter из Member). В вашем ответе предполагается, что Element на самом деле является Elementype, но, учитывая только Element, простое преобразование его в ElementType в целом неверно.

463035818_is_not_a_number 31.10.2018 14:07

@ user463035818 Он ясно говорит, что его Voter является подклассом Member (мой оригинальный Element).

Resurrection 31.10.2018 14:09

да, это подкласс, но если у вас есть Member<VoterA> x; x.asChild()->vote();, приведение не удастся, или я что-то пропущу?

463035818_is_not_a_number 31.10.2018 14:26

@ user463035818 Зачем? Вам разрешено кастовать самому себе. static_cast - вещь времени компиляции.

Resurrection 31.10.2018 14:30

потому что x не является VoterA

463035818_is_not_a_number 31.10.2018 14:33

@ user463035818 А, верно. Это, конечно, обязанность программиста - не делать подобных вещей. :-)

Resurrection 31.10.2018 14:34

да, это более-менее то, что я пытался сказать;). Конечно, также можно было бы включить Member<VoterA> x; x.asChild()->vote();, но мы действительно не знаем, чего хочет OP.

463035818_is_not_a_number 31.10.2018 14:36

@ user463035818 Можно также использовать SFINAE и std::is_base_of, чтобы включить Member, только если MemberType является производным от него. Однако в большинстве случаев я считаю такие вещи излишними. И, конечно же, OP был слишком расплывчатым, чтобы знать точные требования и вариант использования.

Resurrection 31.10.2018 14:40

Другие вопросы по теме