How do you declare an interface in C++?

前端 未结 15 2556
借酒劲吻你
借酒劲吻你 2020-11-22 03:26

How do I setup a class that represents an interface? Is this just an abstract base class?

相关标签:
15条回答
  • 2020-11-22 03:58

    My answer is basically the same as the others but I think there are two other important things to do:

    1. Declare a virtual destructor in your interface or make a protected non-virtual one to avoid undefined behaviours if someone tries to delete an object of type IDemo.

    2. Use virtual inheritance to avoid problems whith multiple inheritance. (There is more often multiple inheritance when we use interfaces.)

    And like other answers:

    • Make a class with pure virtual methods.
    • Use the interface by creating another class that overrides those virtual methods.

      class IDemo
      {
          public:
              virtual void OverrideMe() = 0;
              virtual ~IDemo() {}
      }
      

      Or

      class IDemo
      {
          public:
              virtual void OverrideMe() = 0;
          protected:
              ~IDemo() {}
      }
      

      And

      class Child : virtual public IDemo
      {
          public:
              virtual void OverrideMe()
              {
                  //do stuff
              }
      }
      
    0 讨论(0)
  • 2020-11-22 04:01

    The whole reason you have a special Interface type-category in addition to abstract base classes in C#/Java is because C#/Java do not support multiple inheritance.

    C++ supports multiple inheritance, and so a special type isn't needed. An abstract base class with no non-abstract (pure virtual) methods is functionally equivalent to a C#/Java interface.

    0 讨论(0)
  • 2020-11-22 04:04

    I'm still new in C++ development. I started with Visual Studio (VS).

    Yet, no one seems to mentioned the __interface in VS (.NET). I am not very sure if this is a good way to declare an interface. But it seems to provide an additional enforcement (mentioned in the documents). Such that you don't have to explicitly specify the virtual TYPE Method() = 0;, since it will be automatically converted.

    __interface IMyInterface {
       HRESULT CommitX();
       HRESULT get_X(BSTR* pbstrName);
    };
    

    However, I don't use it because I am concern about the cross platform compilation compatibility, since it only available under .NET.

    If anyone do have anything interesting about it, please share. :-)

    Thanks.

    0 讨论(0)
  • 2020-11-22 04:05

    To expand on the answer by bradtgmurray, you may want to make one exception to the pure virtual method list of your interface by adding a virtual destructor. This allows you to pass pointer ownership to another party without exposing the concrete derived class. The destructor doesn't have to do anything, because the interface doesn't have any concrete members. It might seem contradictory to define a function as both virtual and inline, but trust me - it isn't.

    class IDemo
    {
        public:
            virtual ~IDemo() {}
            virtual void OverrideMe() = 0;
    };
    
    class Parent
    {
        public:
            virtual ~Parent();
    };
    
    class Child : public Parent, public IDemo
    {
        public:
            virtual void OverrideMe()
            {
                //do stuff
            }
    };
    

    You don't have to include a body for the virtual destructor - it turns out some compilers have trouble optimizing an empty destructor and you're better off using the default.

    0 讨论(0)
  • 2020-11-22 04:06

    If you're using Microsoft's C++ compiler, then you could do the following:

    struct __declspec(novtable) IFoo
    {
        virtual void Bar() = 0;
    };
    
    class Child : public IFoo
    {
    public:
        virtual void Bar() override { /* Do Something */ }
    }
    

    I like this approach because it results in a lot smaller interface code and the generated code size can be significantly smaller. The use of novtable removes all reference to the vtable pointer in that class, so you can never instantiate it directly. See the documentation here - novtable.

    0 讨论(0)
  • 2020-11-22 04:06

    You can also consider contract classes implemented with the NVI (Non Virtual Interface Pattern). For instance:

    struct Contract1 : boost::noncopyable
    {
        virtual ~Contract1();
        void f(Parameters p) {
            assert(checkFPreconditions(p)&&"Contract1::f, pre-condition failure");
            // + class invariants.
            do_f(p);
            // Check post-conditions + class invariants.
        }
    private:
        virtual void do_f(Parameters p) = 0;
    };
    ...
    class Concrete : public Contract1, public Contract2
    {
    private:
        virtual void do_f(Parameters p); // From contract 1.
        virtual void do_g(Parameters p); // From contract 2.
    };
    
    0 讨论(0)
提交回复
热议问题