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
}
Related
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.
Following my previous question. I've settled on using using directives to alias types inside my classes to avoid importing other stuff and polluting other headers that use these offending headers.
namespace MyLibrary {
namespace MyModule1 {
class MyClass1 {
public:
float X;
float Y;
MyClass1(float x, float y): X(x), Y(y) {}
};
} // namespace MyModule1
namespace MyModule2 {
class MyClass2 {
private:
// as suggested in linked question
using MyCustomType1 = MyLibrary::MyModule1::MyClass1;
public:
void DoSomething(MyCustomType1 parameter) {
std::cout << parameter.X << std::endl;
std::cout << parameter.Y << std::endl;
}
};
} // namespace MyModule2
} // namespace MyLibrary
int main(int argc, char* argv[])
{
MyLibrary::MyModule1::MyClass1 some_parameter(1.0f, 2.0f);
MyLibrary::MyModule2::MyClass2 some_var;
// Can't do this
// MyLibrary::MyModule2::MyClass2::MyCustomType1 some_other_var;
// But I can do this
some_var.DoSomething(some_parameter);
return 0;
}
How will the users outside of the MyLibrary namespace know what is MyCustomType1 if it is aliased inside a class (privately)?
Is my usage here of using legal, or is this a dirty hack I'm accidentally doing?
They will know for the simple reason you have to #include the declarations of both classes.
Having read this, and the previous question, I think the missing concept here is the concept of forward declarations.
Consider the following header file, let's called this file mymodule1_fwd.H:
namespace MyLibrary {
namespace MyModule1 {
class MyClass1;
} // namespace MyModule1
}
That's it. This is sufficient for you to declare MyClass2:
#include "mymodule1_fwd.H"
namespace MyModule2 {
class MyClass2 {
private:
// as suggested in linked question
using MyCustomType1 = MyLibrary::MyModule1::MyClass1;
public:
void DoSomething(MyCustomType1 parameter);
};
} // namespace MyModule2
Note that including this header file only will not really automatically get the entire MyModule class declaration. Also note the following:
You can't define the contents of the inline DoSomething() class method, because it actually uses the aliased type. This has the following consequences:
You have to define the DoSomething() method somewhere, in some way, probably inside the .C implementation translation module.
Similarly, you have to have declare the actual MyClass1 class from the mymodule1_fwd.H header file. I am using my own personal naming convention here, "filename_fwd.H" for forward declarations, the forward declaration header file; and "filename.H" for the actual class implementation, the implementation header file.
Callers of the DoSomething() method will have to explicitly #include the actual class declaration header file for MyClass, since they have to pass it as a parameter.
You can't really avoid the fact that the callers have to know the class that they're actually using to pass parameters. But only the callers of the DoSomething() method will need that. Something that uses other parts of the MyClass2, and don't invoke DoSomething(), don't need to know anything about MyClass1, and the actual class declaration won't be visible to them unless they explicitly #include the class implementation header file.
Now, if you still need DoSomething() to be inlined, for performance reasons, there are a couple of tricks that can be used, with preprocessor directives, that if someone #includes all the necessary header files, they'll get the inlined declaration of the DoSomething() method.
But that'll have to be another question.
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!
Alright, I just thought give C++ a try (I currently do C#), now my first problem is class instantiating or calling a method in another class.
Here is my code:
My main Program entry:
#include <iostream>
#include "myClass.h"
using namespace std;
int main()
{
myClass* mc = new myClass();
}
The Class I'm trying to access:
#include "myClass.h"
myClass::myClass()
{
void DoSomething();
{
}
}
myClass::~myClass()
{
}
The Class Header:
#pragma once
class myClass
{
public:
myClass();
~myClass();
};
Now as you can see i have instantiated the class, but i cant access DoSomething() method.
This code simply declares a local function, and has an empty scope for fun:
myClass::myClass()
{
void DoSomething(); // local function declaration
{
// empty scope
}
}
If you want doSomething() to be a member of myclass, you have to declare it in the class definition:
class myClass
{
public:
myClass();
~myClass();
void doSomething();
};
then implement it
void myclass::doSomething() { .... }
Also note that you don't have to use new everywhere in C++. You can instantiate an object like this:
int main()
{
myClass mc;
}
Also note that using namespace std; isn't such a great idea anyway, at least not in real code.
this is a function declaration in a constructor (+an ampty scope within { }).
myClass::myClass()
{
void DoSomething();
{
}
}
You want a function declaration in class body (not in constructor) and definition of this function (this can be done immediately together with declaration or later as i.e. here):
class myClass
{
public:
myClass();
~myClass();
void doSomething();
};
implementation of constructor:
myClass::myClass() { .... }
implementation of your function, similarly:
void myClass::doSomething() { .... }
The method you are trying to use in main must be part of the class definition. You can write an inline function or can have a separate definition of that function. Also, you need to make that function public in order to access it from main.
I am having a lot of troubles with my C++ code but I can't understand why.
I am developing a static library libmylib.a that contains myclass.h and myclass.cpp.
The problem I am having is like this:
// myclass.h
class myClass{
public:
myclass();
myclass(a,b);
// some methods.
private:
int a ;
int b ;
};
In myclass.cpp I define the constructors methods etc etc and everything works fine:
I am able to use the library in my main.cpp code.
I then added a friend function:
// myclass.h
class myClass{
public:
myclass();
myclass(a,b);
friend void foo() ;
// some methods.
private:
int a ;
int b ;
};
I define the foo function in myclass.cpp like this
// myclass.cpp
void foo(){
cout << "In foo function " ;
}
The problem is that if I try to use foo() in main.cpp I get a compile error that states:
//main.cpp
#include "myclass.h" // foo() is declared here!
foo() ;
main.cpp:62:6: error: ‘foo’ was not declared in this scope
Now I really can't understand where the problem is.
I notice that after adding the friend function it seems that the linker doesn't use mylib anymore, but I can't understand why. Moreover it is strange, because if I comment foo() in main.cpp myclass and its methods can be used without problems.
What am I doing wrong? I spent two hours trying to figure out, but really can't understand!!!
Solution: following the advice in the answer:
// myclass.h
void foo() ; // the function has to be declared outside the class
class myClass{
public:
myclass();
myclass(a,b);
friend void foo() ; // but here you have to specify that
// is a friend of the class!
// some methods.
private:
int a ;
int b ;
};
This is not a linker error, it is a compiler error. The compiler is telling you that it does not know how to call function foo, because it lacks its definition or declaration.
Declaring a function as a friend is no substitute for a proper declaration. When you say foo is a friend, you do not also introduce foo into a scope. In a sense, friendship declaration is a private detail of your class invisible from the outside.
In order to use a function in C++ you need to declare it first. This is usually done through a header file corresponding to the implementation file, but you can do it simply like this:
void foo();
If foo is defined in the same file as main, you can move foo ahead of the main to fix the problem (seeing a function definition prior to first use is OK with the compiler).
Have you declared foo before using it:
#include "header_where_foo_is_declared.h"
int main()
{
foo();
}
or
void foo();
int main()
{
foo();
}
???