C++ 在不知道子类型的情况下从父类型调用子方法

Posted

技术标签:

【中文标题】C++ 在不知道子类型的情况下从父类型调用子方法【英文标题】:C++ Calling child method from parent type without knowing child type 【发布时间】:2018-06-06 15:24:44 【问题描述】:

我正在尝试将一个项目从 c# 转换为 c++,并且遇到了一个我不确定如何在 c++ 中实现的功能。

我有一个对象列表(或向量),所有对象都转换为它们的父类型。在 c# 中,我可以在不知道子对象的情况下从此列表中的对象调用函数,并且将调用适当的子函数,但是我不确定如何使这个特定功能在 c++ 中工作。

来自 C# 的代码 sn-p:

        public void AddComponent(IComponent component)
    
        Debug.Assert(component != null, "Component must not be null");

        componentList.Add(component);
        mask |= component.ComponentMask;
    

从 Component 中检索 ComponentMask 枚举值并正确执行按位运算。

来自 C++ 的代码 sn-p:

void oEntity::AddComponent(IComponent &componentIn)

    componentList.push_back(componentIn);
    mask |= componentIn.ComponentMask();

这将返回错误“IComponent 无法实例化抽象类”,如果我从方法中删除括号,则运算符重载不再起作用并抛出错误“二进制'|=':未找到采用右手操作数的运算符'overloaded-function' 类型的(或没有可接受的转换)"

掩码值是一个包含位移位整数的枚举,用作标识组件类型的标志。运算符也被适当地重载以使用枚举类型。

【问题讨论】:

我有一个对象列表(或向量),所有对象都转换为它们的父类型。这是 C++ 中的一个问题。您的代码受到object slicing 的影响。请改用std::vector<shared_ptr<IComponent*>> Get a couple of good C++ books 并开始阅读。对于这个问题特别感兴趣,请阅读 pointerspolymophismvirtual functions 在 C++ 中,运行时多态性是基于指针的。您需要IComponent*(或唯一/共享指针)类型的指针的向量/列表,然后存储指向继承类实例的指针。通过这些指针,你就可以调用ComponentMask等虚方法。 更正我之前的评论。请改用std::vector<shared_ptr<IComponent>> 感谢您的快速回复,他们非常有帮助,帮助我解决了问题,也让我在此过程中学到了一些东西。 【参考方案1】:

OP 已经弄清楚了,所以这是给遇到这个问题的其他人的。

在 C++ 中,您可以声明 virtual 方法(您也可以声明 pure 虚拟方法,但这有点复杂)。这些方法可以被子类覆盖,但必须自己实现,否则你会得到一些cryptic errors。

如果您希望它们默认不执行任何操作,最简单的解决方案是使用空主体定义它们。这是一个简单的例子:

class ParentClass

    int x, y;
    virtual void handleNewPos(int newX, int newY)

public:
    ParentClass(int x, int y)
    
        resetPos(x, y);
    

    void resetPos(int newX, int newY)
    
        handleNewPos(newX, newY);
        x = newX;
        y = newY;
    


class ChildClass: public ParentClass

    // marked 'override' because it's replacing a previous virtual method that had the same
    // return type / params. Not required, but if you're using C++11 or greater, than it's
    // preferred 
    virtual void handleNewPos(int newX, int newY) override
    
        // Every time the resetPos method is called, it prints out it's new position.
        std::cout << "New Position: " << newX << ", " << newY << std::endl;
          

public:
    ChildClass(int x, int y): ParentClass(x, y)                                           

【讨论】:

以上是关于C++ 在不知道子类型的情况下从父类型调用子方法的主要内容,如果未能解决你的问题,请参考以下文章

C++:从父实例调用子方法

在不使用 COM 的情况下从 C++ 调用 C# 方法

Python从父调用扩展子方法

如何在不通过 COM 的情况下从 VB6 调用 C++ DLL?

在 JavaScript 中从父级调用子方法

如果尚未调用子组件,如何从父组件调用子组件方法?