I am currently very new to c++, i have started learning how to use pointers in a path finding algorithm.
I am having an issue with calling a function within a class that is derived from a base class.
The specific piece of code causing issue is:
FreeTile *tempPointer = new FreeTile();
cout<<tempPointer->getFree()<<endl;
mapp[i][j] = tempPointer;
when i call getFree (which returns a boolean value) i get the error:
undefined reference to Tile::getFree(). Tile being the base class.
The header for FreeTile is:
#ifndef FREETILE_H
#define FREETILE_H
#include "Tile.h"
class FreeTile:public Tile
{
public:
FreeTile();
virtual ~FreeTile();
void setParent(FreeTile* par);
int getF();
int getG();
int getH();
void setF(int in);
void setG(int in);
void setH(int in);
FreeTile* getParent();
protected:
private:
int F;
int G;
int H;
bool free;
};
Tile header is:
#ifndef TILE_H
#define TILE_H
class Tile
{
public:
Tile();
virtual ~Tile();
bool getFree();
void setFree(bool bo);
protected:
private:
bool free;
};
#endif // TILE_H
#endif // FREETILE_H
Finally the cpp file for Tile:
#include "Tile.h"
#include <iostream>
using namespace std;
bool free;
Tile::Tile()
{
cout<<"Constructor Called"<<endl;
}
Tile::~Tile()
{
//dtor
}
bool getFree(){
return free;
}
void setFree(bool bo){
free = bo;
}
If you need more code or if im missing something blatant feel free to shame me as much as you like :P
Thanks in advance.
On a side note, can you initiate a private variable in a constructor such as free = true as when doing this it states the variable is private.
In the Cpp file rename "bool getFree()" to
"bool Tile::getFree()"
In your implementation the function is just a regular c gloabl function.
In the fixed version it is the class function implementaion of the function you declare in the header file
Also
1st in your Tile you have a private variable "bool free"
in the cpp file you have a global variable "bool free"
this is confusing.
Probably want to delete the one you declared in the cpp file.
Want a deeper explanation?
Yeah! my 1st answer!
Deeper Explanation:
the function you declared in the Class Tile is not defined (just declared) because you didn't add "Tile::" before the function definition in the cpp file (i.e you didn't define a scope).
The function you wrote in the cpp file is both defined and declared in the cpp file, so only functions written after it in the cpp file can call it (works same a c).
Probably when you wrote the function it didn't know that "free" was, right? because it was not a class function. so you added the global "bool free" but that is a completely different variable.
Glad to help!
don't forget to mark this as answered!
Related
I am new at C++ language and I am trying to understand why the next thing is happening:
I have a header file header.h
namespace myNamespace{
class myClass{
public:
myClass();
~myClass();
void myFunction(void);
}
void myVoid();
}
The definitions are in header.cpp
using namespace myNamespace;
void myClass::myFunction(void){
//DO anything
}
void myVoid(){
//Do anything
}
And in the main.cpp I have the follow:
#include "header.h"
main(){
myVoid();
myNamespace::myVoid();
}
Why If I try to call myFunction of the class myClass from the main I have a successful compile, and if I try to call the function as in the main file I have an undefined reference error? I can fix it if in the header.h moves myVoid out of the namespace.
Why is this happening? I am trying to figure out how this works.
Thanks in advice,
If you don't specify definition of myVoid (I mean just declaring it like you did), then the compiler can never be sure if you are implementing the function which is declared in namespace or just defining a new one.
On the other hand, if you are defining myClass::myFunction, it has to be the method that is declared in the defined class.
To make it clear, investigate the following code and take a look here (very similar question)
namespace Test {
int myVoid(void); // declaration
class yourClas; // declaration
class myClass{ // definition
public:
myClass();
~myClass();
void myFunction(void); // declaration which belongs to defined class
}
}
void myVoid() {
// definition, but compiler can't be sure this is the function
// that you mention in the namespace or a new function declaration.
}
void myClass::myFunction(void){
// absolutely definition for the method of the corresponding class
}
Firstly, I am giving the codes. Then I am explaining the problem I am facing.
main.cpp
#include <iostream>
#include "acc.h"
using namespace std;
class mem;
int main()
{
show();
return 0;
}
acc.h
#ifndef ACC_H
#define ACC_H
#include "acc.cpp"
void show();
class mem{
int a;
public:
void showa();
void seta(int A);
};
#endif
acc.cpp
#include <iostream>
using namespace std;
void mem::showa(){cout<<a<<endl;}
void mem::seta(int A){a = A;}
void show()
{
mem m;
m.seta(22);
string ss;
cin>>ss;
cout<<"MY name is "<<ss<<" ";
m.showa();
}
"mem" class I declared in "acc.h" file already and added that "acc.h" into acc.cpp file also. But when I am calling that class from a function. It can't response. Showing "a" and "mem" not declared. How can I perfectly link that class definition and member functions of that class so that calling member functions of that class from another function can't create any problem?
If you remove the #include "acc.cpp" from the acc.h file it should compile without any errors. I tried and it compiles for me. I am using Visual Studio 2010 for the same.
Other than this, few more comments:
You can use #pragma once in you header file instead of #ifndef/#define macros. The former is more cleaner.
You dont need to forward declare class mem before main() as you are already including acc.h.
the show() can be moved to where main() is defined making the acc.h/acc.cppfiles dedicated for the mem class.
A header file should always be named after the class it is holding i.e. mem.h/mem.cpp in your case. This informs which file contains which class even without opening the file.
I am writing a simple banking program with derived classes and I am running into a Multiple definition of <method name> error when including parent class.
Keep in mind that I just started coding in C++ yesterday, and moving over from Java/PHP, handling headers/definitions is a bit confusing for me. Please correct anything you see wrong!
Here is a sample of my files/code:
Files
Account.h
Account.cpp (Super)
ChequingAccount.cpp (Child)
SavingsAccount.cpp (Child)
The error is reproduce-able when including the parent class (Account.cpp) into any file. I have reduced my code by a lot, but it should give you an idea of how I am handling inheritance.
To clarify, when I #include the child classes to any file (ChequingAccount.cpp) works fine, and inherited functions work as expected. However, when I #include the parent class (Account.cpp) breaks the compiler with the Multiple definition of <method name> error for all methods.
Again, I am not sure if this is the proper way to do it, but this is what I understand from tutorials I have found.
Code
Account.h
#ifndef ACCOUNT_H
#define ACCOUNT_H
class Account
{
protected:
double m_balance;
public:
Account(double balance); // Constructor.
virtual ~Account(); // Destructor.
// Accessor Methods.
double getBalance() const;
// Mutator Methods.
virtual void withdrawFunds(double amount);
void depositFunds(double amount);
};
#endif
Account.cpp (Superclass)
#include "Account.h"
Account::Account(double balance = 0)
{
m_balance = balance;
}
Account::~Account()
{
// TODO: Delete this data structure...
}
double Account::getBalance() const
{
return m_balance;
}
void Account::withdrawFunds(double amount)
{
m_balance -= amount;
}
void Account::depositFunds(double amount)
{
m_balance += amount;
}
ChequingAccount.cpp (Child)
#include "Account.h"
class ChequingAccount: public Account
{
public:
ChequingAccount(int id, int userId, double balance) : Account(id, balance){};
void withdrawFunds(double amount)
{
// Override parent method.
}
};
Any help would be greatly appreciated! Thank you!
When you #include "some file.cpp", you are directing the compiler to copy the contents of that cpp file to that point in the program. This will create two compiled versions of your "some file" which will lead to "Multiple Definitions."
First of all, "identical" functions declared in base class and sub-class will not cause multiple definition error.
Here is just one example and explanation aiming to help you understand my point:
main.cpp
class father{
void fun();
}
void father::fun(){}
class son : public father{
void fun();
}
void son::fun(){}
int main()
{
return 0;
}
You compile it, and definitely no multiple definition error. In Java, we define functions within classes. In C++, only inline functions are defined within classes and others are declarations, which can be declared whatever times you like. See the definition syntax : father::fun son::fun. These actually define two different functions, one is in father and the other is in son. So there are no multiple definition error. Once more, in class declarations you can only define inline functions and can only declare non-inline functions. So there are on multiple definition errors at all. This just aims to help you understand it in a grammar way.
BTW, if compiler failed to inline, there would be no multiple definition error too because even though you define inline functions in header files and include the files anywhere, inline functions are of internal linkage.
I compiled your codes and got different errors regarding your defined constructors. Anyway, including cpp files using "include" means you don't get the point of implementation file and interface file.
You need to declare the child's method as a member of the child class explicitly in the child's .cpp file as well. See below:
ChequingAccount.cpp (Child)
#include "Account.h"
class ChequingAccount: public Account
{
public:
ChequingAccount(int id, int userId, double balance) : Account(id, balance){};
void ChequingAccount::withdrawFunds(double amount)
{
// Override parent method.
}
};
You already have void Account::withdrawFunds(double) defined when you define void ChequingAccount::withdrawFunds(double).
Try virtual void ChequingAccount::withdrawFunds(double)
The virtual keyword is similar to overriding in Java.
In short, you should not include a cpp file.
The reason you get a multiple definition error actually has nothing to do with class inheritance.
Consider a simple example:
add.h:
#ifndef __ADD_H_
#define __ADD_H_
int add(int a);
#endif
add.cpp:
#include "add.h"
int add(int a) { return a + 1; }
main.cpp:
#include "add.h"
int main() { return add(-1); }
The way C++ dealing with #include directive is simply to copy-paste the included file and replace the #include line. So if we expand the above files manually, we will get something like:
add.cpp:
#ifndef __ADD_H_
#define __ADD_H_
int add(int a);
#endif
int add(int a) { return a + 1; }
main.cpp:
#ifndef __ADD_H_
#define __ADD_H_
int add(int a);
#endif
int main() { return add(-1); }
which will work just fine. (We are allowed to have multiple declarations of a function)
However, if you decide to include the .cpp file instead of the .h file like the code below:
main.cpp:
#include "add.cpp" // notice here
int main() { return add(-1); }
And if you expand it as we just did:
add.cpp:
#ifndef __ADD_H_
#define __ADD_H_
int add(int a);
#endif
int add(int a) { return a + 1; }
main.cpp:
#ifndef __ADD_H_
#define __ADD_H_
int add(int a);
#endif
int add(int a) { return a + 1; }
int main() { return add(-1); }
You will see the code includes multiple definitions of the function add, one of which is in add.cpp and the other one is in main.cpp. When linking these two files together (each .cpp file is compiled separately using a compiler and then linked together using a linker), the linker will be confused by two definitions of add and doesn't know which one to use, so it will start to complain.
So, i started learning C++ about a year ago, i learned Java C# and VB.NET before it.
As it is now, i would consider myself a advanced C++ coder. However, theres one thing i dont quite get. The linking process. And heres the problem.
Right now, im coding a XNA-like library for Game development, with a basic Component System -
but i get Compiler errors when building it, C++ pretending it doesnt know a specific type, in this case, the GameComponent class doesnt know the ComponentSelector class (and vice versa), although its correctly included and typed. Im gonna show you my two header files, hopefully you can help me out.
ComponentSelector.hpp:
#ifndef COMPONENTSELECTOR_HPP
#define COMPONENTSELECTOR_HPP
#include<sem/System/Types.hpp>
#include<sem/System/GameComponent.hpp>
#include<vector>
namespace sem
{
class ComponentSelector
{
public:
GameComponent* getComponent1(); //GameComponent does not name a type
GameComponent* getComponent2(); //GameComponent does not name a type
GameComponent* getComponent3(); //GameComponent does not name a type
void addComponent(GameComponent* item); //GameComponent does not name a type
void removeComponent1();
void removeComponent2();
void removeComponent3();
void clearList();
private:
std::vector<GameComponent*> m_Components;
protected:
};
}
#endif // COMPONENTSELECTOR_HPP
GameComponent.hpp:
#ifndef GAMECOMPONENT_HPP
#define GAMECOMPONENT_HPP
#include<sem/System/ComponentSelector.hpp>
#include <sem/System/Types.hpp>
namespace sem
{
class GameComponent
{
public:
virtual void load() = 0;
virtual void unload() = 0;
virtual void update() = 0;
virtual void draw() = 0;
ComponentSelector* m_Selector; //ComponentSelector does not name a type
SEMlong getID();
SEMstring getName();
SEMstring getType();
private:
SEMlong m_ComponentID;
SEMstring m_ComponentName;
SEMstring m_ComponentType;
protected:
};
}
#endif // GAMECOMPONENT_HPP
Any solution and tips would be greatly appreciated.
You need a forward declaration for class ComponentSelector in your GameComponent class declaration:
// Remove this: #include<sem/System/ComponentSelector.hpp>
#include <sem/System/Types.hpp>
namespace sem
{
class ComponentSelector; // Note the forward declaration added!
class GameComponent
{
// ...
ComponentSelector* m_Selector; // Compiles now!
// ...
I'd recommend to do the same in the ComponentSelector declaration header vice versa. Include the full class declarations then, where you are going to use any members (this is in the compilation units i.e. .cpp-files usually).
I have a generic class for many states for an automaton. It's declared as follows:
#ifndef STATE_H_
#define STATE_H_
#include "Automat.h"
class State {
public:
virtual void readChar(char c, Automat* automat) = 0;
virtual ~State(){};
};
#endif /* STATE_H_ */
I get this error in eclipse:
Multiple markers at this line
no known conversion for argument 2 from ‘Automat* const’ to ‘int*’
virtual void State::readChar(char, int*)
‘Automat’ has not been declared
My automat is as follows:
#ifndef Automat_H_
#define Automat_H_
#include "../../Scanner/src/IScanner.h"
#include "./States/State.h"
class Automat {
public:
int count;
State* current;
IScanner* scanner;
Automat(IScanner *s);
void readChar(char c);
void setState(State *s);
void error();
~Automat();
};
#endif /* Automat_H_ */
And finally the implementation of Automat, i will leave out some methods.
#include "Automat.h"
#include "./States/StartState.h"
Automat::Automat(IScanner *s) {
current = StartState::makeStartState();
scanner = s;
count = 0;
}
void Automat::readChar(char c) {
current->readChar(c, this);
}
I do not know what causes this. do i need to declare things in an interface? Why does it want to convert the arguments?
Thank you all in advance.
Both headers try to include each other, which is impossible.
Luckily, neither class definition needs the full definition of the other. Each only deals with pointers to the other, for which only a declaration is needed. So replace
#include "Automat.h"
with
class Automat;
and likewise for State.
IMO, I would do that preprocessor stuff in the main file, and just define in each header file one variable, so you know that it's included only once. Also you could do that in "StdAfx.h" if given.
This is just a header mess, please be sure to include it only once. #pragma once may help also.