C++继承"Ignored"

C++ Inheritance "Ignored"

本文关键字:Ignored 继承 C++      更新时间:2023-10-16

我有这个代码块:

struct Road_Primitive {
public:
    Road_GPU_Point A;
    Road_GPU_Point B;
    Road_GPU_Point C;
};
struct Road_Primitive_4P : public Road_Primitive {
    Road_GPU_Point D;
};
struct Road_Primitive_3P : public Road_Primitive{
};

在我的一个类中,我有一个Road_Primitive*,它是用新的Road_Primitive_4Pnew Road_Primitive_3P初始化的,这取决于其他因素。

但是,这段代码给了我一个"类Road_Limit没有成员D":

Road_Primitive* pmtv_Prospect = new Road_Primitive_4P;
pmtv_Prospect->D.X = pch_Rightmost->GPU_Primitive->B.X;

但是,如果我用受保护的成员声明Road_Limit,则错误会变成类似于:"成员B不可访问"

有什么建议吗

好吧,类Road_Primitive没有任何成员D。根据编译器评估的所有子表达式的声明类型来解释每个表达式。pmtv_Prospect当前在执行过程中的某个时刻指向Road_Primitive_4P这一事实并没有被考虑在内——如果您通过Road_Primitive *访问该Road_Primitive_4P,那么您只能访问类Road_Primitive声明的那些成员。

如果希望能够访问Road_Primitive_4P.D,则必须通过(声明的)类型Road_Primitive_4P的值来访问。因此,您可以编写

Road_Primitive_4P* pmtv_Prospect = new Road_Primitive_4P;
pmtv_Prospect->D.X = pch_Rightmost->GPU_Primitive->B.X;

当然,在这种情况下,您不能将pmtv_Prospect指定为指向Road_Primitive_3P,但这确实是要点。如果可以使其指向没有成员DRoad_Primitive_3P,那么访问引用的D是不安全的。

struct Road_Limit实际上没有一个名为D的成员。虽然您正在分配Road_Limit _4P,但您将其存储在指向类型Road_Limit的指针中,因此当您访问(pmtv_Prospect)时,您只能访问Road_Limit中的字段。

通常,当您将子类的实例存储为父类时,您需要多态性和虚拟方法,或者其他一些方法来判断指针真正指向这些子类中的哪个

为了像Gaurav建议的那样使用"dynamic_cast",您的结构或类需要至少有一个虚拟方法。从析构函数开始可能是个好主意:

struct Road_Primitive {
public:
    virtual ~Road_Primitive() {};
// etc.

每个孩子班一个:

struct Road_Primitive_4P: public Road_Primitive {
public:
    virtual ~Road_Primitive_4P() {};

然后,如果您有一个Road_Limit指针,并且想要访问它的成员,而这些成员只能在Road_Limit _4P中访问,则可以使用dynamic_cast:

Road_Primitive_4P* temp = dynamic_cast<Road_Primitive_4P*>(pmtv_Prospect);
if (temp)  // then do something with temp->D

如果对象与您尝试强制转换的类型不匹配,dynamic_cast()将返回0。

还要记住,这种多态性风格通常被认为是糟糕的风格,因为它倾向于将特定的行为集中到不同的类型。使用虚拟方法通常更可取,因为每种类型特定的行为都存储在该类型的定义中。