15

Overview of classes etc of my interface!

Animal.H:

class Animal
{
public:
   virtual void walk();
}

Animals.CPP

=EMPTY

Cow.H:

class Cow : public Animal
{
public:
   virtual void walk();
}

Here it should outomatically know the function walk is taken from the class where it's derived from right? (e.a. Animal..) when i wouldnt define the function walk, it should say i should define it right...?

Cow.CPP:

void Cow::walk()
{
   //do something specific for cow
}

SomeOtherClass.H

namespace SomeNamespace
{
   void LetAnimalWalk();
}

SomeOtherClass.CPP

Cow myCow;
namespace SomeNamespace
{
   void LetAnimalWalk()
   {
      myCow.walk();
   }
}

This should work right?... i mean, the namespace, the "Class::..." things? and the way i inherit and use the interface?

Because this way i get with EVERY FUNCTION i made from the interface, so every virtual function gives me the following error:

SomeOtherClass.obj : error LNK2019: unresolved external symbol "public: virtual void __thiscall Cow::Walk (...etc etc...) referenced in function "void __cdecl SomeNamespace::LetAnimalWalk() (...etc etc...)

Does anyone know what i'm doing wrong, what i do find mostly is that it means i've not declared a function right (somewhere in Cow.cpp??)

Thanks in advance guys

PhilLab
  • 4,777
  • 1
  • 25
  • 77

4 Answers4

15
class Animal
{
public:
   virtual void walk();
}

You need to define that function or make it pure virtual like

class Animal
{
public:
   virtual void walk() = 0;
}
Barış Uşaklı
  • 13,440
  • 7
  • 40
  • 66
  • 1
    But it's virtual right? So when i make a Cow::walk.. i define it.. or ? – Sebastiaan van Dorst Mar 07 '13 at 14:56
  • If the base class function isn't pure virtual you need to define it in the Animal class too. If it is pure virtual in Animal you just need to define it in Cow. Also virtual functions are usually used with pointers to base classes ie `Animal* animal = new Cow(); animal->walk();` that would call the walk function in the cow class. – Barış Uşaklı Mar 07 '13 at 14:59
  • Hmm, i've tried that now too..! It sure is better to use it that way, but still the same errors remain...... – Sebastiaan van Dorst Mar 07 '13 at 15:10
  • Then your code should work, try to post the whole project that reproduces the issue, so we can look at it. – Barış Uşaklı Mar 07 '13 at 15:12
  • Hmm that will be hard, since its a project of a crowd simulation, copyright etc... project from university! And its very big, i will try to make it smaller otherwise, with only the part where this error occurs, then i will post it! Thanks for the help already! ;) – Sebastiaan van Dorst Mar 07 '13 at 15:17
  • Yeah if you can reproduce it with just the files `Animal.h/cpp, Cow.h/cpp, SomeOtherClass.h/cpp` that should be enough. – Barış Uşaklı Mar 07 '13 at 15:18
  • 1
    My bad Baris, your solution "Animal* animal = new Cow(); animal->walk();" i tried.. but in the wrong class.. since i had it in 2 classes, so now i tried it ! and that was it! thanks for the help – Sebastiaan van Dorst Mar 07 '13 at 15:26
11

When you have a virtual function that you don't want to define in the base class, you need to make it abstract, this is done using the following syntax:

class Animal
{
public:
   virtual void walk() = 0;
}

Without this you will get an error if it is not defined, and with this you will get an error if any derived class does not define it.

Jack Aidley
  • 19,439
  • 7
  • 43
  • 70
4

either make the function in the base class pure virtual:

class Animal
{
    public:
        virtual void walk() = 0;
}

or define a trivial implementation:

void Animal::walk()
{
   return;    // could also throw an exception here
}
jerry
  • 2,581
  • 1
  • 21
  • 32
  • I did even define it like you said, this trivial implementation (i made it pure virtual, i defined the implementation, i did both at the same time... but my error remains the same – Sebastiaan van Dorst Mar 07 '13 at 14:59
  • Yes, I see you modified the question, sorry. Your code is obviously simplified, so I'm going to assume you have all the missing `#include` directives in place (otherwise you should be getting an error before the link stage). What development platform are you using? Are you sure `Cow.cpp` is part of your project or makefile? – jerry Mar 07 '13 at 15:06
  • I'm using VS2012... and indeed, includes i didnt put here in the question indeed! Ehm, Cow.cpp as far as i've seen is part of the solution.. i will go check for sure indeed Yea my VS2012, just says its included in project...! :\ – Sebastiaan van Dorst Mar 07 '13 at 15:12
1

Animal* animal = new Cow(); animal->walk();

Cow myCow does NOT work obviously!

  • Calling `walk()` directly on a `Cow` object in fact should work (not give a linker error). The reason you usually call a virtual function through a pointer is to make sure it is in fact called virtually (I wrote a quick example at http://ideone.com/UteSxT). The fact that this fixed your problem tells me there's something else going on. – jerry Mar 07 '13 at 19:00