从成员复制方法
我有一个简单的,低级别的容器类,由更高级别的文件类使用。基本上,文件类使用容器在将最终版本保存到实际文件之前在本地存储修改。因此,一些方法直接从容器类传递到文件类。 (例如,Resize()
。)从成员复制方法
我刚刚定义了文件类中的方法来调用它们的容器类变体。例如:
void FileClass::Foo()
{
ContainerMember.Foo();
}
然而,这是一个滋扰。有一个更好的方法吗?
这里有一个简单的例子:
class MyContainer
{
// ...
public:
void Foo()
{
// This function directly handles the object's
// member variables.
}
}
class MyClass
{
MyContainer Member;
public:
void Foo()
{
Member.Foo();
// This seems to be pointless re-implementation, and it's
// inconvenient to keep MyContainer's methods and MyClass's
// wrappers for those methods synchronized.
}
}
那么,为什么不只是从MyContainer
私下继承,并公开那些你想要转发的函数呢?using
声明?这就是所谓的“以MyContainer
方面实现MyClass
。
class MyContainer
{
public:
void Foo()
{
// This function directly handles the object's
// member variables.
}
void Bar(){
// ...
}
}
class MyClass : private MyContainer
{
public:
using MyContainer::Foo;
// would hide MyContainer::Bar
void Bar(){
// ...
MyContainer::Bar();
// ...
}
}
现在的‘外’就可以直接调用Foo
,而Bar
只是MyClass
内到达。如果你现在做一个函数与相同的名称,它隐藏了基础功能,你可以用这样的基础功能。当然,你现在需要调用完全限定的基础功能,否则你会进入一个无限递归。
另外,我F你要允许MyClass
(非polymorphical)子类,比这是罕见的地方之一,被保护的传承实际上是有用的:
class MyClass : protected MyContainer{
// all stays the same, subclasses are also allowed to call the MyContainer functions
};
非polymorphical如果您MyClass
没有虚析构函数。
是,保持一个代理类这样是很烦人的。您的IDE可能有一些工具使其更容易一些。或者你可以下载一个IDE插件。
但它通常不是非常困难,除非你需要支持几十个函数和覆盖和模板。
我平时写他们喜欢:
void Foo() { return Member.Foo(); }
int Bar(int x) { return Member.Bar(x); }
很高兴和对称。 C++可以让你在void函数中返回void值,因为这会使模板更好地工作。但是你可以使用相同的东西来使其他代码更漂亮。
考虑你的情况有什么意义 - 组合(具有)或继承(是)MyClass和MyContainer之间的关系。
如果你不想再有这样的代码,你几乎只限于实现继承(MyContainer作为基本/抽象基类)。但是,您必须确保这在应用程序中确实是有意义的,并且您不是纯粹为了实现而继承(实现的继承很糟糕)。
如果有疑问,你有什么可能是好的。
编辑:我更习惯于在Java/C#中思考,并忽略了C++具有更大的继承灵活性Xeo在他的答案中使用的事实。在这种情况下,这只是一个很好的解决方案。
这个功能,你需要编写大量的代码实际上是必要的功能。 C++是冗长的语言,如果你试图避免用C++编写代码,你的设计永远不会很好。
但这个问题的真正问题是,这个类没有任何行为。这只是一个什么也不做的包装。每个班级都需要做一些事情,而不是仅仅传递数据。
关键是每个班级都有正确的界面。该要求使得有必要编写转发功能。每个成员函数的主要目的是将所需的工作分配给全部的数据成员。如果你只有一个数据成员,并且你还没有决定班级应该做什么,那么你拥有的只是转发功能。一旦添加了更多的成员对象并决定班级应该做什么,那么你的转发功能将会变得更加合理。
有助于这件事的一件事是保持你的课程小。如果接口很小,那么每个代理类只有很小的接口,接口不会经常更改。
班*做*做些什么。为了解决这个问题,我的例子被简化了。 – Maxpm 2011-05-10 01:51:13
我在这里看到构图,而不是继承。我错过了什么吗? – 2011-05-09 23:22:57
@Doug我只是问几个方法,是否有从容器类继承的方法,或者在我的例子中是'MyContainer'。 (或者更好的解决方案,如果有的话)。我将编辑问题更清楚。 – Maxpm 2011-05-09 23:24:26
在这种情况下,听起来好像你应该将MyContainer分成一个拥有你想要的方法的类(然后继承它)和MyContainer的其他方法的其他类。 – dlev 2011-05-09 23:25:44