0

我遇到了多态性和父子关系的问题。采取以下两个类,并想象在我的应用程序中我创建了一个“孩子”对象。在对象之外,我调用的唯一函数是 update(),它反过来调用对象中我需要的所有其他内容。在这一系列调用中,“父”和“子”中唯一不同的函数是 dosomething2()。

class parent 
{
    public:
        void dosomething1() {}; //amongst other things, calls dosomething2
        void dosomething2() {};
        void update() {}; //amongst other things, calls dosomething1
}

class child : public parent
{
    void dosomething2() {}
}

我意识到,如果我创建一个 'child' 对象并调用 update(),则只会调用父类函数。我不得不将 update() 和 dosomething1() 复制到子类,然后一切都按预期工作。这不是一个很好的解决方案,因为有很多重复的代码 - 有没有办法改进这个?

更新: 感谢提供的答案,我使用虚拟 dosomething2() 函数更新了父类。现在调用了正确的函数,我不必将 dosomething1() 复制到子类。不幸的是,如果我不将 update() 复制到子类,则会出现符号查找错误(父子类都在一个库中)。

class parent 
{
    public:
        void dosomething1() {}; //amongst other things, calls dosomething2
        virtual void dosomething2() {};
        void update() {}; //amongst other things, calls dosomething1
}

class child : public parent
{
    void dosomething2() {}
    /*void update() {}; //symbol lookup error if this is left uncommented */
}

UPDATE2 符号查找错误与代码无关。我做了一个 make clean,然后 make(它构建了一个 .so 库和可执行文件),现在一切都按预期工作了。

4

3 回答 3

3

您没有将基类中的函数标记为虚拟:

class parent 
{
    public:
        virtual void dosomething1() {}; //amongst other things, calls dosomething2
        virtual void dosomething2() {};
        void update() {}; //amongst other things, calls dosomething1
}

另外,仅供参考,您正在做的事情称为模板方法模式

于 2012-08-28T06:17:24.493 回答
2

virtual如果需要,您应该在父类中使用关键字dynamic-polymorphism。然后在子类中重新实现或不重新实现虚函数。

class parent 
{
    public:
        void dosomething1() {}; //amongst other things, calls dosomething2
        virtual void dosomething2() {};
        void update() {}; //amongst other things, calls dosomething1
}
于 2012-08-28T06:18:06.247 回答
1

你应该做相关的功能virtual。假设您想要child'sdoSomething1()doSomething2()被呼叫到update()

class parent 
{
    public:
        virtual void dosomething1() {}; //amongst other things, calls dosomething2
        virtual void dosomething2() {};
        void update() {}; //amongst other things, calls dosomething1
}

class child : public parent
{
    virtual void dosomething2() {}
}

然后,如果可用,对 a 的调用childupdate()调用派生类的方法。请注意,update() is not virtual, so you should have no filed called更新inchild`,否则您将隐藏该名称。

于 2012-08-28T06:18:22.970 回答