Можно ли получить атрибут класса одновременно с классом? - PullRequest
0 голосов
/ 14 декабря 2018

Я прошу сделать Vec, который наследует от ABR.Этот ABR получил 3 указателя в качестве атрибута с типом ABR.Я хотел бы знать, может ли тип этих указателей стать Vec при преобразовании в Vec без параметров шаблона?

вот код соммы, чтобы изобразить его:

class Base
{
protected:
    Base* x;
public:
    Base(): x(nullptr){}
    Base* getVal() {return x;}
};

class Derived: public Base
{
private:
    int y;
public:
    Derived():Base(), y(-1) {}
    Derived(int Y): y(Y){}

    Derived* getVal() {return x;}
    void setVal(Derived *ptr){this->x = ptr;}
};

int main()
{
    Derived D(5), c(7),*ptrToC=&c;
    D.setVal(ptrToC);
    D.getVal();
}

Этот код вернет ошибкув "D.getVal ()", поскольку x по-прежнему является указателем Base, поэтому возможно ли сделать так, чтобы он имел тот же тип, что и класс, в котором он находится?

Ответы [ 2 ]

0 голосов
/ 14 декабря 2018

Здесь вы можете использовать различные способы: простой полиморфизм или шаблоны.

Способ полиморфизма:

В объекте Derived член x при объявлении в качестве Base *будет действительно указывать только на Derived объектов, потому что его значение может быть установлено только на Derived *.Поэтому можно безопасно привести его в getVal:

...
Derived* getVal() {return static_cast<Derived *>(x);}
...

Способ шаблона.

Вы можете использовать любопытно повторяющийся шаблон (CRTP) здесь:

template<class T>
class Base
{
protected:
    T* x;
public:
    Base(): x(nullptr){}
    T* getVal() {return x;}
};

class Derived: public Base<Derived> {
private:
    int y;
public:
    Derived():Base(), y(-1) {}
    Derived(int Y): y(Y){}

    Derived* getVal() {return x;}
    void setVal(Derived *ptr){this->x = ptr;}
};
0 голосов
/ 14 декабря 2018

Единственная опция для этого - шаблоны.Как способ - CRTP идиома:

template <class T>
class Base
{
protected:
   Base* x;
public:
   Base() : x(nullptr) {}
   T* getVal() { return dynamic_cast<T*>(x); }

   virtual ~Base() {}
};

class Derived : public Base<Derived>
{
private:
   int y;
public:
   Derived() :Base(), y(-1) {}
   Derived(int Y) : y(Y) {}

   void setVal(Derived *ptr) { this->x = ptr; }
};

int main()
{
   Derived D(5), c(7), *ptrToC = &c;
   D.setVal(ptrToC);
   D.getVal();
}

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

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