继承和指向受保护成员的指针
Inheritance and pointers to protected members
我目前正在为我正在编写的游戏创建一个基本的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
包括root在内的所有节点都继承了Base的update_internal()方法,我不明白为什么保护它很重要。我认为派生类只能访问私有成员和方法。
只能从派生类的实例中调用基类的受保护/私有函数(当然,除非使用friend
s)。因此,派生类只能访问其基部分的私有/受保护成员,而不能访问其他基部分的成员。在您的情况下,您通过引用中的Base*
来调用它
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 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;
};
相关文章:
- 从成员指针到整个结构/类的强制转换
- OOP 中的单成员指针
- 使用结构成员指针在C++中填充结构
- 聚合初始化,将成员指针设置为同一结构成员
- 空指针常量 (nullptr)、空指针值和空成员指针值之间有什么区别?
- 共享 C++ 的数据成员指针
- 如何声明指向成员内容的成员指针m_pmd/m_pmf并访问它们?
- 从类C++外部调用指向成员方法的成员指针
- 结构成员指针是否自动初始化为零?
- 如何删除类内类类型的类成员指针
- 是否打印指向已定义 int 的成员指针
- 指向常量的成员指针
- 通过此指针访问时的成员差异和自身的成员指针(简单的 QT 示例问题)
- 类数据成员指针的非类型模板参数包无法使用 gcc 编译
- 为什么我不能在同一行中定义两个相同类型的类的成员指针
- 将类成员指针传递给 Lambda 捕获列表 c++11
- 在单一实例类中将成员指针设置为 null 的正确方法是什么
- 无法删除在destructor中的成员指针的课程
- 删除对象而不调用成员指针的析构函数
- 当派生类的基类具有成员指针时,对其进行深层复制