继承和指向受保护成员的指针

3

我正在为我写的游戏创建一个基本的UI系统,它以节点树的形式组织。我试图编写代码,使得只有根节点才能调用其他节点的update方法。我曾经认为自己理解了C++继承,但实际上我的无知让我感到十分尴尬。下面是我尝试创建的一个简单示例:

class Base
{
    public:
        virtual ~Base() { }

    protected:
        virtual void update_internal() = 0;
};

class Node_A : public Base
{
    protected:
        virtual void update_internal() { std::cout << "Update Node A" << std::endl; }
};

class Node_B : public Base
{
    protected:
        virtual void update_internal() { std::cout << "Update Node B" << std::endl; }
};

class Root : public Base
{
    public:
        void add_node (Base* node) { m_nodes.push_back(node); }

        void update()
            {
                for (auto& node : m_nodes)
                {
                    node->update_internal();
                }
            }

    protected:
        std::vector<Base*> m_nodes;
        virtual void update_internal() { }
};


int main()
{
    Node_A alpha_node;
    Node_B beta_node;
    Root root_node;

    root_node.add_node(&alpha_node);
    root_node.add_node(&beta_node);

    root_node.update();
}

当我尝试编译时,GCC报错如下:
error: 'virtual void Base::update_internal()' is protected

所有的节点包括根节点都从Base类继承了update_internal()方法,我不明白为什么它是protected类型。我以为只有私有成员和方法是派生类无法访问的。


2
https://dev59.com/wmgu5IYBdhLWcg3wCCtK - Amadeus
4个回答

4
您只能从派生类的实例中调用基类的受保护/私有函数(除非您使用friend)。因此,派生类只能访问其基本部分的私有/受保护成员,而不能访问其他基类的成员。在您的情况下,您通过对Base*的引用来调用它。
for(auto& node : m_nodes)
     node->update_internal();

因此编译器会发出警告。


2

只需与Base和Root成为好友;

class Base
{
    friend class Root; // <- yes,this
    public:
        virtual ~Base() { }

    protected:
        virtual void update_internal() = 0;
};

1
这是模板方法模式的一个典型示例。
Root类的公共方法公开了需要在内部实现的内容。

1
class Base
{
protected:
    virtual void update_internal() = 0;

    static void DoUpdate( Base *node )
    {
        node->update_internal();
    }
};

class Root : public Base
{
public: 
    void update()
    {
        for (auto node : m_nodes)
        {
            Base::DoUpdate( node );
        }
    }
protected:
    virtual void update_internal() override {}
    std::vector<Base*> m_nodes;
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接