简体   繁体   中英

Implement java like interface in C++

I would like to create an Animal interface. The Cat class implements it. An animal can eat an another animal eat(Animal a) . Animal.die() will kill the animal, and Animal.isDead() returns, if the animal is dead, or not.

If I would like to compile it, I get some errors:

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

I've searched a lot, how to fix this errors. But none of them resolved it. I'm not a C++ expert. I only have some years of JAVA experience.

Code:

#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;
}

Your problem is with generics. They are not the same as templates, even if their syntax is somewhat similar.

Replace:

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

With:

virtual void eat(Animal*);

And your code compiles. Java basically does the above, but when you call eat it stores the runtime type of A and will under some circumstances cast it back to that type for you. In C++ you are responsible for doing that cast yourself.

You can duplicate most or all of what Java does with generics with template tomfoolery, but it is rarely worth the bother.

Firts of all you must specify public inheritance statement to use your Animal interface in polymorphism manner.

class Cat: public Animal

Secondly C++ template declaration slightly differs from Java

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

in method defenition

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

so you code must appear that way

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM