-1

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;
}
Iter Ator
  • 8,226
  • 20
  • 73
  • 164
  • 4
    Please consult a basic book on C++. – Kerrek SB Dec 20 '15 at 23:01
  • 2
    Looks like you're guessing. You can't learn `C++` that way. I suggest working methodically through a good book: https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – Galik Dec 20 '15 at 23:07
  • As much as it is a bad idea to try and write Java while thinking in C++, it also is a bad idea to try and write C++ while thinking in Java. Many well designed C++ programms are far from the almost pure OO-approach, that is typical for Java. – cdonat Dec 20 '15 at 23:16
  • `Implement java like interface in C++` Umm...No. – PaulMcKenzie Dec 20 '15 at 23:56
  • I don't want to write the C++ code in JAVA style. I just want to figure out, how to solve the same problem in C++ – Iter Ator Dec 21 '15 at 00:27

2 Answers2

3

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.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
1

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;
}
KoliaX
  • 78
  • 1
  • 8