派生类调用非公共基类虚拟函数

Derived Class Calling Non-Public Base Class Virtual Function

本文关键字:基类 虚拟 函数 调用 派生      更新时间:2023-10-16

编辑:

这个问题已经在这里被问过了但对我的情况没有帮助。我正在尝试使用继承的公共update()函数建立类的层次结构。但我希望给定的派生派生类在进行自己的处理之前调用其所有基类的功能。我实际的VS2013解决方案由一个引用DLL项目的EXE项目组成,但下面的简化代码仍然会产生错误:

// Map.h (in DLL project)
namespace Game2D {
    class Map {
    public:
        explicit Map();
        ~Map();
        void update(double);
    protected:
        virtual void baseUpdates(double dt) {}
    };
}
// Map.cpp (in DLL project)
namespace Game2D {
    Map::Map() { }
    Map::~Map() {}
    void Map::update(double dt) {
        baseUpdates(dt);
        // Do some base stuf...
    }
}
// AutoScrollMap.h (in DLL project)
namespace Game2D {
    class AutoScrollMap : public Map {
    public:
        explicit AutoScrollMap();
        ~AutoScrollMap();
    protected:
        virtual void baseUpdates(double) {}
    };
}
// AutoScrollMap.cpp (in DLL project)
namespace Game2D {
    AutoScrollMap::AutoScrollMap() : Game2D::Map() {}
    AutoScrollMap::~AutoScrollMap() {}
    void AutoScrollMap::baseUpdates(double dt) {
        // Do some stuff...
    }
}
// DesertMap.h (in EXE project)
namespace Shooter {
    class DesertMap : public Game2D::AutoScrollMap {
    public:
        explicit DesertMap();
        ~DesertMap();
    protected:
        virtual void baseUpdates(double);
    };
}
// DesertMap.cpp (in EXE project)
namespace Shooter {
    DesertMap::DesertMap() : Game2D::AutoScrollMap() {}
    DesertMap::~DesertMap() {}
    void DesertMap::baseUpdates(double dt) {
        AutoScrollMap::baseUpdates(dt);
        // Do more specific stuff...
    }
}

这给了我一个编译器错误"错误C2084:函数'void Game2D::AutoScrollMap::baseUpdates(double)'已经有一个主体"。上面的文章说我可以使用这个语法来调用一个正在重载的函数。然而,它的例子中的基函数是公共的,而不是受保护的,我真的想保护baseUpdates(),因为它不是接口的一部分。

我认为这个问题是OOP继承范式的一个相当基本的使用,那么我缺少什么呢?非常感谢所有的建议!

您描述的方法没有问题,问题出在您的代码中。您已经内联实现了Derived2::baseUpdates(),然后尝试再次定义它。您应该将Derived2更改为:

class Derived2 : public Derived1 {                                              
    public:                                                                     
        Derived2() : Derived1() { }                                             
    protected:                                                                  
        virtual void baseUpdates();                                             
};                                                                              

void Derived2::baseUpdates() {                                                  
    Derived1::baseUpdates();                                                    
}

此外,您的Base构造函数也未实现。

哇,试图将此代码简化为最简单的形式以获得帮助实际上揭示了问题。我已经在AutoScrollMap.h中的baseUpdates()后面放了大括号"{}",因此出现了"函数已经有正文"错误。看起来您确实可以从派生重写中调用基本虚拟函数,即使基本函数不是公共的!很抱歉浪费了大家的时间,哈哈。