0

I am trying to compile a C++ program. I am learning the "virtual functions" concept. So I was trying to see what happens when we override a function without making it "virtual".
I have three directories headers, sources and objects.
In the header directory, I have 2 files, Pokemon.h and Charmander.h . In the sources directory, I have 3 files Pokemon.cpp, Charmander.cpp and Main.cpp.
class Charmander in Charmander.h, inherits from class Pokemon from Pokemon.h.

This is Pokemon.h in the "headers" directory:

/********************************************************************************
 * Pokemon --                                                                   *
 * This is the base class for all pokemons. Every pokemon will inherit from     *
 * this class.                                                                  *
 *                                                                              *
 * Author -- Aditya R.Singh                                                     *
 * Version -- 1.0                                                               *
 * Since -- 2014-06-21                                                          *
 ********************************************************************************/ 



#ifndef POKEMON_H
#define POKEMON_H



using namespace std;



class Pokemon {

    public:
        string type();
        string attack();
        string weakness();
};    



#endif   

This is Charmander.h in the "headers" directory:

/*******************************************************************************
 * Charmander --                                                               *
 * This class is the derived class from class Pokemon. This is specialized for *
 * the pokemon Charmander.                                                     *
 *                                                                             *
 * Author -- Aditya R.Singh                                                    *
 * Version -- 1.0                                                              *
 * Since -- 2014-06-18                                                         *
 *******************************************************************************/



#ifndef CHARMANDER_H
#define CHARMANDER_H



#include "Pokemon.h"  



using namespace std;



class Charmander: public Pokemon {

    public:
        string type();
        string attack();
        string weakness();
};    



#endif  

This is the Pokemon.cpp in the "sources" directory:

/**********************************************************************************
 * Pokemon --                                                                     *
 * This is the implementation of functions in class Pokemon.                      *
 * This is a generic class for every pokemon.                                     *
 *                                                                                *
 * Author -- Aditya R.Singh                                                       *
 * Since -- 1.0                                                                   *
 * Version -- 2014-06-21                                                          *
 **********************************************************************************/



#include <iostream>
#include "../headers/Pokemon.h"



using namespace std;



string Pokemon::type() {

    return "Normal";
}    



string Pokemon::attack() {

    return "Headbutt";
}



string Pokemon::weakness() {

    return "Fighting";
}   

This is the Charmander.cpp file in the "sources" directory:

/**********************************************************************************
 * Charmander --                                                                  *
 * This is the Charmander class's functions implementations.                      *
 * This is specific to Charmander.                                                *
 *                                                                                *
 * Author -- Aditya R.Singh                                                       *
 * Since -- 1.0                                                                   *
 * Version -- 2014-06-21                                                          *
 **********************************************************************************/



#include <iostream>
#include "../headers/Charmander.h"



using namespace std;



string Charmander::type() {

    return "Fire";
} 



string Charmander::attack() {

    return "Fireflame";
}



string Charmander::weakness() {

    return "Water";
}  

And this is the Main.cpp file in the "sources" directory:

/**********************************************************************************
 * Main --                                                                        *
 * This program will show the use of Polymorphism and Inheritance in C++.         *
 *                                                                                *
 * Author -- Aditya R.Singh                                                       *
 * Since -- 1.0                                                                   *
 * Version -- 2014-06-21                                                          *
 **********************************************************************************/



#include <iostream>
#include "../headers/Pokemon.h"
#include "../headers/Charmander.h"



using namespace std;



int main() {

    Pokemon *charmander = new Charmander;   



    cout << "Charmander is a " << charmander->type() << " type pokemon." << endl;
    cout << "Charmander can do a " << charmander->attack() << " attack." << endl;
    cout << "Charmander is weak against " << charmander->weakness() << " type pokemon." << endl;



    return 0;
}  

Now I compiled the Pokemon.cpp and put the object file in the "objects" directory... Currently my terminal is in the "Program" directory...

gcc -c sources/Pokemon.cpp -o objects/Pokemon.o  

I compiled the Charmander.cpp and the put the object file in the "objects" directory... like this ..

gcc -c sources/Charmander.cpp -o objects/Charmander.o  

It's working fine uptill now. I have the object files in the "objects" directory now.

But now I am trying to compile my Main.cpp like this..

gcc sources/Main.cpp -o Main objects/Pokemon.o objects/Charmander.o  

But my GCC compiler gives some big error stack like, undefined symbols for architecture x86_64.

I am using a mac book pro, 64 bit machine. OS Mac OS X maverics.

Aditya Singh
  • 2,343
  • 1
  • 23
  • 42
  • 3
    You should post the error message, or at least some of it. – RichieHindle Jun 21 '14 at 06:58
  • 1
    Even if this "works", I expect you should `#include ` before using the string type - not sure that's your problem, as you haven't provided the error messages. – Mats Petersson Jun 21 '14 at 07:00
  • You're learning C++, but you then enter the world of Java programming by doing this: `Pokemon *charmander = new Charmander;` In C++, there is no need to use `new` to create an object. – PaulMcKenzie Jun 21 '14 at 07:00
  • Make sure you don't have any other files called Pokemon.h . The Charmander.h's `#include "Pokemon.h" ` will search the same way that it does from your .cpp files, if you also had Pokemon.h in the sources then it finds that first. Actually things are a lot simpler if you put source and headers in the same directory; and you can symlink them to another directory if you want external access. – M.M Jun 21 '14 at 07:01
  • @MatsPetersson I tried that. but still the same error persists. – Aditya Singh Jun 21 '14 at 07:01
  • @PaulMcKenzie maybe you overlooked that he wants polymorphism? – M.M Jun 21 '14 at 07:01
  • @MattMcNabb But I want to keep them separate. Coz of I don't know why. I have seen people doing it. And I too feel convenient that way. – Aditya Singh Jun 21 '14 at 07:03
  • @MattMcNabb - Yes, I see that now. What is missing is the call to `delete`. – PaulMcKenzie Jun 21 '14 at 07:03
  • @PaulMcKenzie What is the delete thing you talking about? And i used the **new** keyword coz I did not want to create a Charmander object separately and make it point by Pokemon class variable. – Aditya Singh Jun 21 '14 at 07:05
  • @Aditya In C++ when you allocate memory with `new`, you're supposed to deallocate the memory using `delete`. Otherwise you will get a memory leak. – PaulMcKenzie Jun 21 '14 at 07:08
  • @PaulMcKenzie Oh yeah! Thanks for the tip. Heard that for the first time. Can you give me the syntax? – Aditya Singh Jun 21 '14 at 07:10
  • @Aditya - Where did you learn `new`? Wherever it was, that same source of information should have had `delete` explained to you. – PaulMcKenzie Jun 21 '14 at 07:11
  • Have you heard of copyright - http://en.wikipedia.org/wiki/The_Pok%C3%A9mon_Company – Ed Heal Jun 21 '14 at 07:15
  • @PaulMcKenzie I saw the `new` keyword on the internet somewhere. They did not have anything like `delete`. – Aditya Singh Jun 21 '14 at 07:20
  • @EdHeal Dude, This is just an example, for educational purpose. Relax. – Aditya Singh Jun 21 '14 at 07:23
  • 1
    @Aditya - C++ is a language that can't be learned in an ad-hoc manner. There will be other issues that you won't know about if you just learn "by ear". – PaulMcKenzie Jun 21 '14 at 07:43
  • @Aditya - Using a copyright without may land you in hot water. Educational or otherwise. I am relaxed but using copyright material is on your shoulders. Not mine – Ed Heal Jun 21 '14 at 08:22
  • @EdHeal. it's fine. I don't think they would mind. – Aditya Singh Jun 21 '14 at 08:24
  • @Aditya - Well ask them! Perhaps they might mind. Me for one with my copyright mind. It is my income – Ed Heal Jun 21 '14 at 08:39
  • I think they would like it seeing people getting educated using their pokemons. lol – Aditya Singh Jun 21 '14 at 12:46
  • @EdHeal I see no copyright issues here. Perhaps you meant trademark issues? – M.M Jun 21 '14 at 12:53
  • @MattMcNabb - Either way you are on dodgy ground – Ed Heal Jun 21 '14 at 15:31

2 Answers2

1

To get polymorphic behaviour, the base class must have at least one virtual function.

Add to the class definition of Pokemon:

virtual ~Pokemon() { }

Note that since your other functions are not virtual, charmander->type() will call Pokemon::type(), not Charmander::type().

NB. Your code compiles correctly for me, with the addition of #include <string>. If you still have problems then try moving everything to the same directory , in case you are perhaps having one unit pick up an old version of a header file from a different directory.

M.M
  • 138,810
  • 21
  • 208
  • 365
  • Thanks, So what changes should I make in my code/s? Infact, I want it to call type() from Pokemon class using the Charmander object. Coz I want to demo a call to a non virtual function. – Aditya Singh Jun 21 '14 at 07:11
  • yes, I did. thanks. actually I was using a gcc compiler in place of g++. – Aditya Singh Jun 21 '14 at 12:44
  • OK. Start a new question for things that aren't directly related to this question. And accept the answer of the guy who answered corectly! – M.M Jun 21 '14 at 12:52
1

You should use g++ instead of gcc to compile and link C++ programs so that the C++ library gets properly linked in.

See https://stackoverflow.com/a/5854712/12711 for the gory details.

Community
  • 1
  • 1
Michael Burr
  • 333,147
  • 50
  • 533
  • 760
  • OH MY GOD!!!! This was the exact problem I had. Oh yeah! Thankyou! Thankyou! Thankyou! Uhh! How careless...... :D :D :D I never made that mistake before. Don't know why it happened this time. lol. Thankyou. – Aditya Singh Jun 21 '14 at 07:19
  • It's an easy mistake to make. – Michael Burr Jun 21 '14 at 07:24