Можно ли получить атрибут класса одновременно с классом?

Я прошу сделать 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 ответа

Здесь есть способы, будь то простой полиморфизм или шаблоны.

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

В 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;}
};

Единственная возможность сделать это - шаблоны. Как способ - 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

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