在C ++中实现接口功能

时间:2009-07-16 01:40:30

标签: c++ oop memory pointers interface

我使用OOP的一个重要原因是创建易于重用的代码。为此,Java风格的界面是完美的。但是,在处理C ++时,我实际上无法实现任何类型的功能,比如接口......至少不容易。

我知道纯虚拟基类,但真正让我感到震惊的是,它们会让我陷入使用指针的笨拙代码。例如。 map<int, Node*> nodes;(其中Node是虚拟基类)。

这有时是好的,但有时指向基类只是不可能的解决方案。例如。如果要返回打包为接口的对象,则必须返回一个指向对象的基类类指针..但该对象位于堆栈上,并且在返回指针后不会存在。当然,你可以开始大量使用堆来避免这种情况,但这会增加比应有的更多的工作(避免内存泄漏)。

有没有办法在C ++中实现类似接口的功能而不必笨拙地处理指针和堆? (老实说,所有的麻烦和尴尬都只是坚持C。)

6 个答案:

答案 0 :(得分:4)

你可以使用boost :: shared_ptr&lt; T&gt;避免原始指针。作为旁注,您没有在Java语法中看到指针的原因与C ++如何实现接口与Java如何实现接口无关,而是由于Java中的所有对象都是隐式指针(*隐藏)。

答案 1 :(得分:2)

模板MetaProgramming非常酷。基本的想法? “编译时间多态和隐式接口”, Effective C ++ 。基本上,您可以通过模板化类获得所需的接口。 非常简单示例:

template <class T>
bool foo( const T& _object )
{
    if ( _object != _someStupidObject && _object > 0 )
        return true;
    return false;
}

那么在上面的代码中我们可以对对象T说些什么呢?那么它必须与'_someStupidObject'兼容,或者它必须可以转换为兼容的类型。它必须与积分值相当,或者再次转换为类型。所以我们现在已经为类T定义了一个接口。“Effective C ++”一书提供了更好,更详细的解释。希望上面的代码能让您对模板的“接口”功能有所了解。还可以看看几乎所有的升级库,它们几乎都充满了模板化。

答案 2 :(得分:0)

考虑到C ++不需要generic parameter constraints like C#,那么如果您可以使用它,则可以使用boost::concept_check。当然,这只适用于有限的情况,但是如果你可以使用它作为你的解决方案,那么你肯定会有更快的代码和更小的对象(更少的可用开销)。

使用vtables的动态分派(例如,纯虚拟基础)将使您的对象在实现更多接口时增大。 Managed languages do not suffer from this problem (this is a .NET link, but Java is similar).

答案 3 :(得分:0)

我认为你的问题的答案是否定的 - 没有更简单的方法。如果你想要纯粹的接口(好吧,你可以在C ++中获得纯粹的接口),你将不得不忍受所有的堆管理(或尝试使用垃圾收集器。还有其他问题,但我的关于这个问题的观点是,如果你想要一个垃圾收集器,请使用一个用Java设计的语言。就像Java)。

在某种程度上缓解堆管理痛苦的一个重要方法是自动指针。 Boost有一个很好的自动指针,可以为你做很多堆管理工作。 std :: auto_ptr有效,但在我看来它很古怪。

您还可以评估是否真的需要这些纯接口。有时你会这样做,但有时候(就像我使用的一些代码一样),纯接口只能由一个类实例化,因此只是成为额外的工作,对最终产品没有任何好处。

答案 4 :(得分:0)

虽然auto_ptr有一些奇怪的使用规则,你必须知道*,但它的存在是为了让这种事情变得容易。

auto_ptr<Base> getMeAThing() {
    return new Derived();
}


void something() {
    auto_ptr<Base> myThing = getMeAThing();
    myThing->foo();  // Calls Derived::foo, if virtual
    // The Derived object will be deleted on exit to this function.
}

*永远不要将auto_ptrs放在容器中。了解他们在任务中所做的事情是另一个。

答案 5 :(得分:0)

这实际上是C ++闪耀的案例之一。事实上,C ++提供的模板和函数没有绑定到类,这使得重用比纯面向对象语言更容易。但实际情况是,您必须调整编写代码的方式,以便利用这些优势。来自纯OO语言的人通常会遇到这种困难,但在C ++中,对象接口不包含成员函数。实际上,在C ++中使用非成员函数来尽可能地实现对象接口被认为是一种很好的做法。一旦你开始使用模板非成员函数来实现接口,那么它就是一种改变生活的体验。 \