C++ 类的某些成员只能由基类访问吗?
我有一个C++ 类的某些成员只能由基类访问吗?,c++,inheritance,protected,composite,C++,Inheritance,Protected,Composite,我有一个Widget类和一个派生自它的CompositeWidgetCompositeWidget添加子管理行为。Widget构造函数将一个CompositeWidget*参数作为Widget的父项。我需要使用此父指针访问CompositeWidget中的某些功能。例如: Widget::Widget(CompositeWidget* parent) { parent_->AddChild(*this); } 这迫使我创建一个公共方法CompositeWidget::AddChi
Widget
类和一个派生自它的CompositeWidget
CompositeWidget
添加子管理行为。Widget
构造函数将一个CompositeWidget*
参数作为Widget的父项。我需要使用此父指针访问CompositeWidget
中的某些功能。例如:
Widget::Widget(CompositeWidget* parent)
{
parent_->AddChild(*this);
}
这迫使我创建一个公共方法CompositeWidget::AddChild
。是否可以将此接口保持为类层次结构的私有接口(有点像反向-受保护
访问-仅限于基类)?我在思考这样的问题时是否犯了设计错误
编辑:我试图避免友谊(如果在这种情况下可能的话)。使用
朋友
关键字
class Widget { ... };
class CompositeWidget {
friend class Widget;
};
但是,您也可以在
小部件
类上插入virtual
方法AddChild
。使用friend
关键字
class Widget { ... };
class CompositeWidget {
friend class Widget;
};
但是,您也可以在小部件
类上插入virtual
方法AddChild
这迫使我创建一个公共方法
不,您可以声明:
friend class Widget;
在CompositeWidget声明中。然而
我是在设计失礼吗
有一个引用派生类的父类方法可能有一点设计缺陷,但我不会说这是绝对错误的
这迫使我创建一个公共方法
不,您可以声明:
friend class Widget;
在CompositeWidget声明中。然而
我是在设计失礼吗
拥有一个引用派生类的父类方法可能有一点设计缺陷,但我不会说这是绝对错误的。回答你的具体问题:声明
小部件
成为你的复合Widget
的朋友,并使AddChild
成为私有成员
或者,将子管理移动到CompositeWidget
。本书在以下章节中对此进行了详细讨论:
该决定涉及安全性和透明度之间的权衡:
- 在类层次结构的根目录定义子管理接口可以提高透明度,因为可以统一处理所有组件。然而,这会让您付出安全代价,因为客户端可能会尝试做一些毫无意义的事情,比如从叶子中添加和删除对象
- 在复合类< /强>中定义子管理<强>为您提供安全性,因为任何试图从叶中添加或移除对象的方法都会在编译时捕获,如C++中的静态类型语言。但是你会失去透明度,因为树叶和复合材料有不同的界面
在这种模式中,我们强调透明度而非安全性。如果你
选择安全,有时您可能会丢失类型信息并
将构件转换为复合构件的步骤。没有你怎么能做到这一点
求助于不安全类型转换
他们接着给出了一个很长的代码示例,基本上可以归结为这样的设计,CompositeWidget
包含子管理:
class Widget
{
public:
//
virtual Composite* GetComposite() { return 0; }
}
class CompositeWidget: public Widget
{
public:
void AddChild(Component*);
// ...
virtual Composite* GetComposite() { return this; }
};
class LeafWidget: public Widget
{
// no child management here
};
GetComposite
允许您查询小部件以查看它是否是复合部件。你
可以在返回的组合上安全地执行AddChild
。回答您的具体问题:声明Widget
为您的CompositeWidget
的朋友,并使AddChild
成为private
成员
或者,将子管理移动到CompositeWidget
。本书在以下章节中对此进行了详细讨论:
该决定涉及安全性和透明度之间的权衡:
- 在类层次结构的根目录定义子管理接口可以提高透明度,因为可以统一处理所有组件。然而,这会让您付出安全代价,因为客户端可能会尝试做一些毫无意义的事情,比如从叶子中添加和删除对象
- 在复合类< /强>中定义子管理<强>为您提供安全性,因为任何试图从叶中添加或移除对象的方法都会在编译时捕获,如C++中的静态类型语言。但是你会失去透明度,因为树叶和复合材料有不同的界面
在这种模式中,我们强调透明度而非安全性。如果你
选择安全,有时您可能会丢失类型信息并
将构件转换为复合构件的步骤。没有你怎么能做到这一点
求助于不安全类型转换
他们接着给出了一个很长的代码示例,基本上可以归结为这样的设计,CompositeWidget
包含子管理:
class Widget
{
public:
//
virtual Composite* GetComposite() { return 0; }
}
class CompositeWidget: public Widget
{
public:
void AddChild(Component*);
// ...
virtual Composite* GetComposite() { return this; }
};
class LeafWidget: public Widget
{
// no child management here
};
GetComposite
允许您查询小部件以查看它是否是复合部件。你
可以在它返回的组合上安全地执行AddChild
。你能让Widget
成为CompositeWidget
的朋友吗?最上面的CompositeWidget呢?它将什么指针传递给它的基本小部件c'tor?这似乎是一个糟糕的设计。GoF书籍设计模式在Composite@TemplateRex很遗憾,这本书不是我的。你能发布一个回复,转达其中的一些信息吗?@DanNestor:复合模式也可以在网上找到-你能让<代码>小部件
成为<代码>复合网页
的朋友吗?最上面的复合网页呢?它将什么指针传递给它的基本小部件c'tor?这似乎是一个糟糕的设计。GoF书籍设计模式在Composite@TemplateRex很遗憾,这本书不是我的。你能给我一个回复,转达一些信息吗