如何设置表示接口的类?这只是一个抽象基类吗?


当前回答

我还是C++开发的新手。我从Visual Studio(VS)开始。

然而,似乎没有人提到VS(.NET)中的__interface。我不太确定这是否是声明接口的好方法。但它似乎提供了额外的强制执行(文件中提到)。这样就不必显式指定虚拟TYPE Method()=0;,因为它将被自动转换。

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

然而,我不使用它,因为我担心跨平台编译兼容性,因为它只在.NET下可用。

如果有人对此感兴趣,请分享。:-)

谢谢

其他回答

您还可以考虑使用NVI(非虚拟接口模式)实现的合约类。例如:

struct Contract1 : boost::noncopyable
{
    virtual ~Contract1() = default;
    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:
    void do_f(Parameters p) override; // From contract 1.
    void do_g(Parameters p) override; // From contract 2.
};
class Shape 
{
public:
   // pure virtual function providing interface framework.
   virtual int getArea() = 0;
   void setWidth(int w)
   {
      width = w;
   }
   void setHeight(int h)
   {
      height = h;
   }
protected:
    int width;
    int height;
};

class Rectangle: public Shape
{
public:
    int getArea()
    { 
        return (width * height); 
    }
};
class Triangle: public Shape
{
public:
    int getArea()
    { 
        return (width * height)/2; 
    }
};

int main(void)
{
     Rectangle Rect;
     Triangle  Tri;

     Rect.setWidth(5);
     Rect.setHeight(7);

     cout << "Rectangle area: " << Rect.getArea() << endl;

     Tri.setWidth(5);
     Tri.setHeight(7);

     cout << "Triangle area: " << Tri.getArea() << endl; 

     return 0;
}

结果:矩形面积:35三角形面积:17

我们已经看到了抽象类是如何根据getArea()定义接口的,另外两个类实现了相同的函数,但使用了不同的算法来计算特定于形状的面积。

下面是c++标准中抽象类的定义

第4687页

13.4.2

抽象类是只能用作其他类的基类的类;没有抽象对象类只能作为派生类的子对象来创建。如果类至少具有一个纯虚拟函数。

以上都是好答案。还有一件事你应该记住——你也可以有一个纯粹的虚拟析构函数。唯一的区别是你仍然需要实现它。

困惑的


    --- header file ----
    class foo {
    public:
      foo() {;}
      virtual ~foo() = 0;

      virtual bool overrideMe() {return false;}
    };

    ---- source ----
    foo::~foo()
    {
    }

你想这样做的主要原因是,如果你想提供接口方法,就像我所说的那样,但让重写它们成为可选的。

要使类成为接口类,需要一个纯虚方法,但所有的虚方法都有默认实现,因此唯一剩下的方法就是析构函数。

在派生类中重新实现析构函数根本没什么大不了的——我总是在派生类里重新实现一个析构函数,不管是虚拟的还是非虚拟的。

使用纯虚拟方法创建类。通过创建另一个重写这些虚拟方法的类来使用该接口。

纯虚拟方法是定义为虚拟并分配给0的类方法。

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

class Child : public IDemo
{
    public:
        virtual void OverrideMe()
        {
            // do stuff
        }
};