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


当前回答

除了C#/Java中的抽象基类之外,您还有一个特殊的接口类型类别,这是因为C#/Java不支持多重继承。

C++支持多重继承,因此不需要特殊类型。没有非抽象(纯虚拟)方法的抽象基类在功能上等同于C#/Java接口。

其他回答

就我所能测试的而言,添加虚拟析构函数非常重要。我使用的是用new创建的对象,用delete销毁的对象。

如果不在接口中添加虚拟析构函数,则不会调用继承类的析构函数。

class IBase {
public:
    virtual ~IBase() {}; // destructor, use it to call destructor of the inherit classes
    virtual void Describe() = 0; // pure virtual method
};

class Tester : public IBase {
public:
    Tester(std::string name);
    virtual ~Tester();
    virtual void Describe();
private:
    std::string privatename;
};

Tester::Tester(std::string name) {
    std::cout << "Tester constructor" << std::endl;
    this->privatename = name;
}

Tester::~Tester() {
    std::cout << "Tester destructor" << std::endl;
}

void Tester::Describe() {
    std::cout << "I'm Tester [" << this->privatename << "]" << std::endl;
}


void descriptor(IBase * obj) {
    obj->Describe();
}

int main(int argc, char** argv) {

    std::cout << std::endl << "Tester Testing..." << std::endl;
    Tester * obj1 = new Tester("Declared with Tester");
    descriptor(obj1);
    delete obj1;

    std::cout << std::endl << "IBase Testing..." << std::endl;
    IBase * obj2 = new Tester("Declared with IBase");
    descriptor(obj2);
    delete obj2;

    // this is a bad usage of the object since it is created with "new" but there are no "delete"
    std::cout << std::endl << "Tester not defined..." << std::endl;
    descriptor(new Tester("Not defined"));


    return 0;
}

如果在没有virtual~IBase(){};的情况下运行前面的代码;,您将看到从未调用析构函数Tester::~Tester()。

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

困惑的


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

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

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

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

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

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

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

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

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

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

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

谢谢

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

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

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

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

我的答案与其他人基本相同,但我认为还有两件重要的事情要做:

如果有人试图删除IDemo类型的对象,请在接口中声明一个虚拟析构函数或创建一个受保护的非虚拟析构器,以避免未定义的行为。使用虚拟继承来避免多重继承的问题。(当我们使用接口时,通常会有多重继承。)

和其他答案一样:

使用纯虚拟方法创建类。通过创建另一个重写这些虚拟方法的类来使用该接口。类IDemo{公众:虚空OverrideMe()=0;virtual~IDemo(){}}或类IDemo{公众:虚空OverrideMe()=0;受保护的:~IDemo(){}}和class Child:虚拟公共IDemo{公众:虚拟空OverrideMe(){//做一些事情}}