代码之家  ›  专栏  ›  技术社区  ›  Junier

在C++中实现接口功能

  •  0
  • Junier  · 技术社区  · 15 年前

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

    我知道纯虚拟基类,但真正让我恼火的是,它们强迫我使用指针编写非常笨拙的代码。例如。 map<int, Node*> nodes; (其中node是虚拟基类)。

    这有时是可以的,但有时指向基类的指针只是不可能的解决方案。例如,如果要返回打包为接口的对象,则必须返回指向该对象的基类强制转换指针。但该对象在堆栈中,返回指针后不会出现在堆栈中。当然,您可以开始广泛地使用堆来避免这种情况,但这会增加比应该做的更多的工作(避免内存泄漏)。

    有没有办法在C++中实现接口类功能,而不必笨拙地处理指针和堆呢?(老实说,尽管有那么多麻烦和尴尬,我还是坚持用C。)

    6 回复  |  直到 15 年前
        1
  •  2
  •   DeusAduro    15 年前

    模板元编程是一件很酷的事情。基本的想法?”编译时多态性和隐式接口“, 有效C++ . 基本上,你可以通过模板化的类得到你想要的接口。一 非常 简单例子:

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

    所以在上面的代码中,我们可以对t对象说些什么呢?好吧,它必须与“somestupidobject”兼容,或者它必须可以转换为兼容的类型。它必须与整数值相比较,或者再次转换为一种类型。因此,我们已经为T类定义了一个接口。“有效C++”一书提供了一个更好和更详细的解释。希望上面的代码能让您了解模板的“接口”功能。也可以看看几乎所有的Boost图书馆,它们几乎都是用粉笔画出来的模板。

        2
  •  4
  •   Michael Aaron Safyan    15 年前

    您可以使用boost::shared_ptr<t>来避免原始指针。另一方面,在Java语法中没有看到指针的原因与C++如何实现接口与Java如何实现接口无关,而是由于Java中的所有对象都是隐式指针(*是隐藏的)。

        3
  •  0
  •   Sam Harwell    15 年前

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

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

        4
  •  0
  •   Michael Kohne    15 年前

    我认为你的问题的答案是否定的——没有比这更容易的方法了。如果你想要纯接口(很好,就像C++中的纯),你必须忍受所有堆管理(或者尝试使用垃圾收集器)。关于这个主题还有其他问题,但我对这个主题的看法是,如果您想要一个垃圾收集器,请使用一种与垃圾收集器一起设计的语言。像Java一样。

    减轻堆管理痛苦的一个大方法是自动指针。Boost有一个很好的自动指针,它可以为您完成大量堆管理工作。自动测试是可行的,但在我看来这很奇怪。

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

        5
  •  0
  •   Mike Elkins    15 年前

    虽然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.
    }
    

    *首先,不要把自动驾驶仪放在集装箱里。理解他们在任务中做的是另一件事。

        6
  •  0
  •   Frank Lane    15 年前

    这实际上是C++中闪亮的例子之一。C++提供了不绑定到类的模板和函数,这使得重用比纯面向对象语言容易得多。但现实情况是,为了利用这些好处,您必须调整编写代码的方式。来自纯OO语言的人通常会遇到困难,但是在C++中,对象接口不包括成员函数。事实上,它被认为是在C++中使用非成员函数来实现对象接口的良好实践。一旦你掌握了使用模板非成员函数来实现接口的窍门,那么这是一种改变生活的体验。\