继承和指向受保护成员的指针
Inheritance and pointers to protected members
我目前正在为我正在编写的游戏创建一个基本的 UI 系统。它被组织为节点树。我正在尝试编写它,以便只有根节点可以调用其他节点上的更新方法。我以为我懂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
包括root在内的所有节点都继承了Base的update_internal()方法,我不明白为什么保护它很重要。我以为只有私有成员和派生的方法 类 无法访问。
您只能从派生 class 的实例调用基 class 的 protected/private 函数(当然除非您使用 friend
s)。所以派生的 class 只能访问其基础部分的 private/protected 成员,而不能访问其他基础部分的成员。在你的例子中,你通过引用 Base*
in
来调用它
for(auto& node : m_nodes)
node->update_internal();
所以编译器报错。
只是和 Base 和 Root 成为朋友;
class Base
{
friend class Root; // <- yes,this
public:
virtual ~Base() { }
protected:
virtual void update_internal() = 0;
};
这是 Template Method 模式的库存示例。
Root
class 的 public 方法公开了内部需要实现的内容。
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;
};
我目前正在为我正在编写的游戏创建一个基本的 UI 系统。它被组织为节点树。我正在尝试编写它,以便只有根节点可以调用其他节点上的更新方法。我以为我懂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
包括root在内的所有节点都继承了Base的update_internal()方法,我不明白为什么保护它很重要。我以为只有私有成员和派生的方法 类 无法访问。
您只能从派生 class 的实例调用基 class 的 protected/private 函数(当然除非您使用 friend
s)。所以派生的 class 只能访问其基础部分的 private/protected 成员,而不能访问其他基础部分的成员。在你的例子中,你通过引用 Base*
in
for(auto& node : m_nodes)
node->update_internal();
所以编译器报错。
只是和 Base 和 Root 成为朋友;
class Base
{
friend class Root; // <- yes,this
public:
virtual ~Base() { }
protected:
virtual void update_internal() = 0;
};
这是 Template Method 模式的库存示例。
Root
class 的 public 方法公开了内部需要实现的内容。
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;
};