C++ C++;:通过向下转换到派生类来扩展对象

C++ C++;:通过向下转换到派生类来扩展对象,c++,inheritance,parent-child,downcast,C++,Inheritance,Parent Child,Downcast,我想这是一个经典,但在我的例子中,我有一些约束条件可以简化问题 只是我在模块的输入端得到了一些结构,并想给它添加一些属性。所以我创建了一个结构B,它扩展了a,并添加了我需要的内容 现在,每当我调用一个方法,该方法需要一个B,但我给它一个a,编译器都会不高兴:a对象可能不是B,就像所有的猫科动物都不是狮子一样 但在我的情况下,我发誓所有As都是B,尽管属性较少。找不到的属性可以报告为未初始化,这很好,我还发誓在初始化属性之前我永远不会调用它。基本上,当获取A对象作为输入时,我要做的第一件事是填充剩

我想这是一个经典,但在我的例子中,我有一些约束条件可以简化问题

只是我在模块的输入端得到了一些结构,并想给它添加一些属性。所以我创建了一个结构B,它扩展了a,并添加了我需要的内容

现在,每当我调用一个方法,该方法需要一个B,但我给它一个a,编译器都会不高兴:a对象可能不是B,就像所有的猫科动物都不是狮子一样

但在我的情况下,我发誓所有As都是B,尽管属性较少。找不到的属性可以报告为未初始化,这很好,我还发誓在初始化属性之前我永远不会调用它。基本上,当获取A对象作为输入时,我要做的第一件事是填充剩余的B属性,它们是基于A属性计算的。我只是不想复制As,因为我进入Bs只是为了添加一些属性,因为这样As的属性就会被复制到内存中。我也不会修改A的原始属性,我只是用它们来计算派生属性,然后用A属性和派生属性来传递和处理B对象

例如:

从通用的项目范围标题:

struct Rectangle {
    // Side lengths
    int a,b;
}
从本地标题:

struct LocalRectangle : Rectangle {
    int area;
}

void updateModule(Rectangle inputRect);
从当地来源:

void updateModule(Rectangle inputRect) {
    LocalRectangle r = (LocalRectangle)inputRect;
    r.area = r.a*r.b;
    // More processing ...
}
我该怎么做

提前感谢,


<查尔斯>

如果你可以修改<代码> a < /c>结构,你可以考虑只将这些值添加到<代码> a <代码>中,使用未初始化的值(使用指针或)并懒惰地初始化它们。p>

否则,如果您不能修改<代码> A<代码>,也不想将每个代码的值复制到<对应的代码> b>代码>,您可以考虑使用<代码> b>代码> <强> < <强> >源于<代码> A<代码>,只需附加属性即可。然后,您将维护一个全局

std::map
[1],并通过查看映射来查找其他属性。如果选择此路径,请询问自己是否知道何时从
映射中删除过时的
A
s


  • 我使用的是
    A*
    ,因为您希望避免复制
    A
    s

  • 如果A是一个具有较少属性的B,那么它不是一个B,是吗?否则,我们将能够从世界上的任何对象强制转换到任何其他对象,只需查找具有相同名称/签名的属性/方法

    但我不得不质疑,为什么要传入一个类型不正确的对象。如果该方法不需要B提供的额外属性,则将其签名更改为采用A*而不是B*。如果它确实需要这些值,那么就不能传入没有这些值的对象


    如果你真的真的必须这么做,我想你看到我不认为它是一个好的设计,那么也许考虑在某个地方做一个静态的方法,拿一个A,然后返回一个新的B,把未知的属性设置为NULL或某物。< /P>你可以把代码放在后面吗?也许你可以把一个字段添加到结构类型<代码> STD::MAP<代码>它将保存不同的属性,并删除Bs结构,这是类型A的所有内容。您可以修改

    A
    ?std::map听起来比必要的更复杂(而且资源贪婪)。我不能修改,其他人会使用它们。无论如何,我不需要这样做。请注意,在您的示例中,您通过值传递
    Rectangle
    ,因此您无论如何都要复制它。在这种情况下,您不妨复制到
    LocalRectangle