是否可以与课程同时导出课程属性?

时间:2018-12-14 15:04:05

标签: c++ derived

我要求做一个继承自ABR的Vec。该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 :(得分:0)

执行此操作的唯一选项是模板。作为一种方式-CRTP惯用语:

[
  {
    "modifed": "2018-09-05T14:33:29.816-04:00",
    "Path": "/index/library/abc"
  },
  {
    "modifed": "2018-09-05T14:33:29.867-04:00",
    "Path": "/index/library/abc_form/abc_thankyou"
  },
  {
    "modifed": "2018-09-05T14:33:29.892-04:00",
    "Path": "/index/library/abc_form/abc_thankyou_d"
  },
  {
    "modifed": "2018-09-05T14:33:29.841-04:00",
    "Path": "/index/library/abc_form"
  },
  {
    "modifed": "2018-09-05T14:33:29.788-04:00",
    "Path": "/index/library/index"
  },
  {
    "modifed": "2018-09-05T14:33:29.763-04:00",
    "Path": "/index/library"
  },
  {
    "modifed": "2018-09-05T14:33:29.565-04:00",
    "Path": "/index/contact/contact-thankyou"
  },
  {
    "modifed": "2018-09-05T14:33:29.511-04:00",
    "Path": "/index/contact"
  },
  {
    "Lastmodifed": "2018-09-05T14:33:29.402-04:00",
    "Path": "/index/downloads/downloads-thank-you"
  },
  {
    "Lastmodifed": "2018-09-05T14:33:29.427-04:00",
    "Path": "/index/downloads/downloads-thank-you-abc"
  },
  {
    "Lastmodifed": "2018-09-05T14:33:29.376-04:00",
    "Path": "/index/downloads"
  },
  {
    "Lastmodifed": "2018-09-05T14:33:25.520-04:00",
    "Path": "/index"
  }
]

还要注意,您的代码中没有多态性。您需要通过添加至少一个虚拟方法(例如析构函数)来为path: "index" modified : "2018-09-05T14:33:25.520-04:00" |____ path: "library" modified : "2018-09-05T14:33:29.763-04:00" |____ path: abc modified : "2018-09-05T14:33:29.816-04:00" |____ path: index modified : "2018-09-05T14:33:29.788-04:00" |____ path: abc_form modified : "2018-09-05T14:33:29.841-04:00" |___ path: abc_thankyou modified : "2018-09-05T14:33:29.867-04:00" |___ path: abc_thankyou_d modified : "2018-09-05T14:33:29.892-04:00" |____ path: "contact" modified : "2018-09-05T14:33:29.511-04:00" |____ path: contact-thankyou modified : "2018-09-05T14:33:29.565-04:00" |____ path: "downloads" modified : "2018-09-05T14:33:29.376-04:00" |____ path: downloads-thank-you modified : "2018-09-05T14:33:29.402-04:00" |____ path: downloads-thank-you-abc modified : "2018-09-05T14:33:29.427-04:00" 创建一个虚拟函数表。除非您当然想将Base转换为Derived

答案 1 :(得分:0)

您必须在这里使用简单的多态性或模板。

多态方式:

Derived对象中,x成员在被声明为Base *时实际上仅指向Derived对象,因为其值只能设置为Derived *。因此将其强制转换为getVal

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

模板方式。

您可以在此处使用curiously recurring template pattern (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;}
};