#include <cstring>
class thing{
public:
thing();
virtual ~thing();
void setName(char *name){strcpy(m_Name,name);}
char* getName(void){return m_Name;}
protected:
char m_Name[20];
};
class fromThing: public thing{
public:
fromThing();
virtual ~fromThing();
void setDisc(char *name){strcpy(m_Disc,name);}
char* getDisc(void){return m_Disc;}
protected:
char m_Disc[50];
};
int main(){
thing* myThing = new fromThing();
myThing.setName("myThing");
myThing.setDisc("its My Thing");
return 0;
}
or do i have to do this: fromThing* myThing = new fromThing();
and not have any polymorphic functionality?
also why is it that when i change it to fromThing myThing = new fromThing(); (or its actual equivalent, as this is just a simplified example of what i want to do.)
g++ tells me
1 2 3 4 5
g++ -Wall -I src -I src/game -o build/0.1/zlg src/main.cpp
/tmp/ccGVZQx8.o: In function `main':
main.cpp:(.text+0x30): undefined reference to `room::room(char const*)'
main.cpp:(.text+0x49): undefined reference to `thing::setDisc(charconst*)'
main.cpp:(.text+0x5c): undefined reference to `thing::setVDisc(char const*)'
it doesnt have line numbers, but im guessing that its complaining cause those fuctions are actually declaired as room::room(constchar *)
are strings that you enter in a functions parameters (like func("this");) always considered char const *
#include <cstring>
class thing{
public:
thing();
virtual ~thing();
void setName(char *name){strcpy(m_Name,name);}
char* getName(void){return m_Name;}
virtualvoid setDisc();
virtualchar* getDisc();
protected:
char m_Name[20];
};
class fromThing: public thing{
public:
fromThing();
virtual ~fromThing();
virtualvoid setDisc(char *name){strcpy(m_Disc,name);}
virtualchar* getDisc(void){return m_Disc;}
protected:
char m_Disc[50];
};
int main(){
thing* myThing = new fromThing();
myThing->setName("myThing");
myThing->setDisc("its My Thing");
return 0;
}
and im getting
1 2 3 4
g++ lol.cpp
lol.cpp: In function ‘int main()’:
lol.cpp:35: error: no matching function for call to ‘thing::setDisc(constchar [13])’
lol.cpp:11: note: candidates are: virtualvoid thing::setDisc()
so im guessing that if i declare a virtual function i have to over ride it exactly, so i have to over ride
#include <cstring>
class thing{
public:
thing();
virtual ~thing();
void setName(char *name){strcpy(m_Name,name);}
char* getName(void){return m_Name;}
virtualvoid setDisc();
virtualchar* getDisc();
protected:
char m_Name[20];
};
class fromThing: public thing{
public:
fromThing();
virtual ~fromThing();
virtualvoid setDisc(char *name){strcpy(m_Disc,name);}
virtualchar* getDisc(void){return m_Disc;}
protected:
char m_Disc[50];
};
int main(){
fromThing* myThing = new fromThing();
myThing->setName("myThing");
myThing->setDisc("its My Thing");
return 0;
}
i get this from g++
1 2 3 4
g++ lol.cpp
/tmp/ccAyN3vk.o: In function `main':
lol.cpp:(.text+0x28): undefined reference to `fromThing::fromThing()'
collect2: ld returned 1 exit status
which is interesting cause i thought it was going to give me undefined ref to 'setName(char const*)'
As I've said: you have to define functions before using them.
which is interesting cause i thought it was going to give me undefined ref to 'setName(char const*)'
why? setName if defined in thing and inherited from it.
I dont understand why do you use so many virtual functions. You realy dont need virtual destructors becouse they cant be inherited. You dont need functions setDisc and getDisc in class this at all unles you intend to create an object of that class. You also dont need keyword virtual before function setDisc and getDisc unles you are going to write a class derieved from fromThing and redefine them.
Can other functions? I always thought it was a class concept.
On the other hand, if you have a base class without a virtual destructor, the base-classes destructor won't be called if a derived classes destructor gets called which is a Bad Thing. I think the committee made an error when they decided that the default constructor is not 'virtual' (they could have provided the possibility to override the virtaul default destructor with a non-virtual implementation). You have to provide your own implementation, even if it's empty (which you should *always* do - remember, it is still legal C++ code if you don't (meaning: it compiles), but your objects won't be destructed properly if you inherit from them).
By the way, use std::string instead of char arrays (what happens if your "name" gets larger than 20?) if you don't have very good reasons not to (which you most likely don't). And prefer "private" to "protected" member variables and use getter and setter functions (what you did anyways). That way, validity checking (if needed sometime) has to be done only once and is consistent for all derived classes (e.g., in your implementation you would have to check if the char-arrays are large enough. With a setter function this has to be implemented only once)
Do inherited virtual functions call their base class versions when used?
No (if not explicitly called, that is) - except for the constructor and the destructor, provided that the latter is virtual. (That is, by the way, one of the reasons why you should not inherit from stl containers).
Edit. To clarify, try:
1 2 3 4 5 6 7 8 9 10 11 12
class A
{
public:
A()
{
std::cout<<"A constructed"<<std::endl;
}
~A()
{
std::cout<<"A destroyed"<<std::endl;
}
};
... same with B and virtual destructor
now write a C and D which inherit from A/B and print a similar message. Create an C/D object and look what happens.
why? setName if defined in thing and inherited from it.
cause this is an example program for the point of keeping my post short, which it really didnt succeed at. (which i ment to point out but may not have, whoops. )
its for the most part the same as what im actually trying to compile however having less functions and thats what its complaining about in my other one where im doing things the same.
(well i dont have virtual written all through my other files but otherwise its the same, hence the fourth point in the first .)
in any case. i think im slowly working out the linker issues.... im now getting whilst trying to compile that example program that i wrote for this thread. (i replaced the ; after the constructors and destructors with {})
1 2 3 4 5 6 7 8
g++ lol.cpp
/tmp/cc235eL6.o: In function `thing::thing()':
lol.cpp:(.text._ZN5thingC2Ev[thing::thing()]+0x4): undefined reference to `vtable for thing'
/tmp/cc235eL6.o: In function `thing::~thing()':
lol.cpp:(.text._ZN5thingD2Ev[thing::~thing()]+0x7): undefined reference to `vtable for thing'
/tmp/cc235eL6.o:(.rodata._ZTV9fromThing[vtable for fromThing]+0x10): undefined reference to `thing::setDisc()'
/tmp/cc235eL6.o:(.rodata._ZTI9fromThing[typeinfo for fromThing]+0x8): undefined reference to `typeinfo for thing'
collect2: ld returned 1 exit status