2011-05-09 67 views
5

我有一个简单的,低级别的容器类,由更高级别的文件类使用。基本上,文件类使用容器在将最终版本保存到实际文件之前在本地存储修改。因此,一些方法直接从容器类传递到文件类。 (例如,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. 
    } 
} 
+0

我在这里看到构图,而不是继承。我错过了什么吗? – 2011-05-09 23:22:57

+0

@Doug我只是问几个方法,是否有从容器类继承的方法,或者在我的例子中是'MyContainer'。 (或者更好的解决方案,如果有的话)。我将编辑问题更清楚。 – Maxpm 2011-05-09 23:24:26

+1

在这种情况下,听起来好像你应该将MyContainer分成一个拥有你想要的方法的类(然后继承它)和MyContainer的其他方法的其他类。 – dlev 2011-05-09 23:25:44

回答

7

那么,为什么不只是从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没有虚析构函数。

1

是,保持一个代理类这样是很烦人的。您的IDE可能有一些工具使其更容易一些。或者你可以下载一个IDE插件。

但它通常不是非常困难,除非你需要支持几十个函数和覆盖和模板。

我平时写他们喜欢:

void Foo()  { return Member.Foo(); } 
int Bar(int x) { return Member.Bar(x); } 

很高兴和对称。 C++可以让你在void函数中返回void值,因为这会使模板更好地工作。但是你可以使用相同的东西来使其他代码更漂亮。

1

考虑你的情况有什么意义 - 组合(具有)或继承(是)MyClass和MyContainer之间的关系。

如果你不想再有这样的代码,你几乎只限于实现继承(MyContainer作为基本/抽象基类)。但是,您必须确保这在应用程序中确实是有意义的,并且您不是纯粹为了实现而继承(实现的继承很糟糕)。

如果有疑问,你有什么可能是好的。

编辑:我更习惯于在Java/C#中思考,并忽略了C++具有更大的继承灵活性Xeo在他的答案中使用的事实。在这种情况下,这只是一个很好的解决方案。

0

这个功能,你需要编写大量的代码实际上是必要的功能。 C++是冗长的语言,如果你试图避免用C++编写代码,你的设计永远不会很好。

但这个问题的真正问题是,这个类没有任何行为。这只是一个什么也不做的包装。每个班级都需要做一些事情,而不是仅仅传递数据。

关键是每个班级都有正确的界面。该要求使得有必要编写转发功能。每个成员函数的主要目的是将所需的工作分配给全部的数据成员。如果你只有一个数据成员,并且你还没有决定班级应该做什么,那么你拥有的只是转发功能。一旦添加了更多的成员对象并决定班级应该做什么,那么你的转发功能将会变得更加合理。

有助于这件事的一件事是保持你的课程小。如果接口很小,那么每个代理类只有很小的接口,接口不会经常更改。

+0

班*做*做些什么。为了解决这个问题,我的例子被简化了。 – Maxpm 2011-05-10 01:51:13