用C++实现类java接口

Implement java like interface in C++

本文关键字:java 接口 实现 C++      更新时间:2023-10-16

我想创建一个Animal接口。Cat类实现了它。一只动物可以吃掉另一只动物eat(Animal a)Animal.die()会杀死动物,如果动物已经死亡或没有死亡,Animal.isDead()会返回。

如果我想编译它,我会得到一些错误:

templates may not be 'virtual'
invalid use of incomplete type 'class A'
expected class-name before '{' token

我搜索了很多,如何修复这些错误。但他们都没有解决。我不是C++专家。我只有几年的JAVA经验。

代码:

#include <iostream>
using namespace std;
//interface
class Animal {
public:
    template<class A extends Animal>
    virtual void eat(A* a) = 0;
    virtual void die() = 0;
    virtual bool isDead() = 0;
};
// Cat class
class Cat: Animal {
private:
    bool dead = false;
public:
    Cat();
    Cat(const Cat& orig);
    virtual ~Cat();
    template<class A extends Animal>
    void eat(A* a);
    void die();
    bool isDead();
};
// Implement cat
Cat::Cat() {
}
Cat::Cat(const Cat& orig) {
}
Cat::~Cat() {
}

template<class A extends Animal>
void Cat::eat(A* a) {
    a->die();
}
void Cat::die() {
    dead = true;
}
bool Cat::isDead() {
    return dead;
}
int main(int argc, char** argv) {
    Cat* cat = new Cat();
    Cat* cat2 = new Cat();
    cat->eat(cat2);
    cout << (cat2->isDead()? "Cat2 is dead" : "Cat2 is not dead") << endl;
    return 0;
}

您的问题是泛型。它们与模板不同,即使它们的语法有些相似。

替换:

template<class A extends Animal>
virtual void eat(A* a);

带有:

virtual void eat(Animal*);

然后您的代码就会编译。Java基本上完成了上述操作,但当您调用eat时,它会存储A的运行时类型,并在某些情况下为您将其强制转换回该类型。在C++中,你有责任为自己铸造。

您可以用模板技术复制Java对泛型所做的大部分或全部操作,但这很少值得麻烦。

首先,您必须指定公共继承语句才能以多态方式使用Animal接口。

class Cat: public Animal

其次,C++模板声明与Java 略有不同

template <class T>
class ClassName
{
    void ClassMethod(T* pObject);
};

方法内防御

template <class T>
void ClassName<T>::ClassMethod(T* pObject)
{
}

所以你的代码必须以这种方式出现

template <class A>
class Animal {
public:
    virtual void eat(A* a) = 0;
    virtual void die() = 0;
    virtual bool isDead() = 0;
};
// Cat class
template <class A>
class Cat: public Animal<A> {
private:
    bool dead = false;
public:
    Cat();
    Cat(const Cat<A>& orig);
    virtual ~Cat();
    void eat(A* a);
    void die();
    bool isDead();
};
// Implement cat
template <class A>
Cat<A>::Cat() {
}
template <class A>
Cat<A>::Cat(const Cat<A>& orig) {
}
template <class A>
Cat<A>::~Cat() {
}

template<class A>
void Cat<A>::eat(A* a) {
    a->die();
}
template <class A>
void Cat<A>::die() {
    dead = true;
}
template <class A>
bool Cat<A>::isDead() {
    return dead;
}
int main(int argc, char** argv) {
    Cat<Cat>* cat = new Cat<Cat>();
    Cat<Cat>* cat2 = new Cat<Cat>();
    cat->eat(cat2);
    cout << (cat2->isDead()? "Cat2 is dead" : "Cat2 is not dead") << endl;
    return 0;
}