我要求做一个继承自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指针,是否有可能使其与他所在的类具有相同的类型?
答案 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;}
};