I'm trying to work with classes in separate files in CodeBlocks but I'm getting the following problem.
I have 3 files: main.cpp, clasa.h and clasa.cpp.
clasa.h
#pragma once
class clasa
{
public:
clasa();
};
clasa.cpp
#include "clasa.h"
#include <iostream>
using namespace std;
clasa::clasa()
{
cout<<"hi";
}
main.cpp
#include <iostream>
#include "clasa.h"
using namespace std;
int main()
{
clasa obj;
return 0;
}
When I include these 3 files into a project, the output is hi.
When I DON'T include them into a project, main.cpp just doesn't build. But if i replace "clasa.h" with "clasa.cpp" it works again.
Why does it not work otherwise?
TL;DR - It looks like you are not compiling the header file (*.h) in the the built executable.
When you click the run button the computer does two things. First it compiles the code and makes an executable. Then it runs the executable.
First how does the compiler work?
It reads *.cpp and when it comes across "#include" it replaces that line the code from the specified file. After the compiler processes the #include "clasa.h" line the main.cpp file will look like this:
#include <iostream>
#pragma once
class clasa
{
public:
clasa();
};
using namespace std;
int main()
{
clasa obj;
return 0;
}
It does the same for the also.
When you remove the *.h file from the project the compiler does not include the code in the executable.
The reason it works with the *.cpp variant is because the compiler does not include *.cpp files. They are accessed as the program in run.
Hope this helped you.
Related
While following the book C++ For Dummies, I have three files in my CodeBlocks project, main.cpp, Pen.h, and Pen.cpp. They look like this:
main.cpp:
#include <iostream>
#include "Pen.h"
//#include "Pen.cpp"
using namespace std;
int main()
{
Pen MyPen = Pen();
MyPen.test();
}
Pen.h:
#ifndef PEN_H_INCLUDED
#define PEN_H_INCLUDED
//#include "Pen.cpp" // Uncommenting this gives a different error
using namespace std;
class Pen
{
public:
// attributes omitted
// PROTOTYPES:
// other functions omitted
void test();
};
#endif // PEN_H_INCLUDED
Pen.cpp:
#include <iostream>
#include "Pen.h"
using namespace std;
//other function definitions omitted
void Pen::test()
{
cout << "Test successful." << endl;
}
When I run the code as listed above, I get an "undefined reference to `Pen::test()'" error. To fix this, I changed the #include statements at the top of main.cpp to:
#include <iostream>
//#include "Pen.h"
#include "Pen.cpp"
This works as intended and correctly prints out "Test successful."
My question is this: what in the world is the point of putting a function prototype in a header file if I have to import the .cpp file later on anyways?
EDIT: It turns out this was a problem with not knowing how to use Code::Blocks rather than with the C++ language.
Assuming you're using gcc, you can compile and link in one step by supplying multiple .cpp files via the command line.
g++ Pen.cpp main.cpp
clang should be similar.
clang++ Pen.cpp main.cpp
An #include should never reference a .cpp file. At all. There's no good reason to do it. Include your headers and then supply the names of all .cpp files when you compile. If your project gets big and you have too many .cpp files to reasonably list, then it's time to break out a makefile or similar.
In the main.cpp include the header file:
#include "Pen.h"
The Pen.h file it's ok.
You need to add the Pen.cpp file to the project tree.
Go to Project -> Add files... and add Pen.cpp
I'm trying to learn how to utilize header files in C++ projects, so I made .cpp files containing simple functions to make sure I'm doing all the declaring and including correctly.
Everything worked fine when I only had one set of .cpp and .h files, but when I try to add more I get errors.
To start with, in my project I had:
helloworld.cpp
#include "helloworld.h"
#include <iostream>
#include <cstdio>
using namespace std;
int HelloWorld() {
puts("Hello, World!");
cout << "Hello, World!" << endl;
return 0;
}
helloworld.h
#ifndef HELLOWORLD_H_INCLUDED
#define HELLOWORLD_H_INCLUDED
int HelloWorld();
#endif /* HELLOWORLD_H_INCLUDED */
main.cpp
#include "helloworld.h"
#include <iostream>
using namespace std;
int main(){
HelloWorld();
return 0;
}
Which built with no errors and ran correctly.
Next I tried adding a second .cpp and .h file, which created building errors.
pointers.cpp
#include "pointers.h"
#include <iostream>
using namespace std;
int Pointers() {
int x = 1;
int *ptr_a = &x;
cout << *ptr_a << endl;
return 0;
}
pointers.h
#ifndef POINTERS_H_INCLUDED
#ifndef POINTERS_H_INCLUDED
int Pointers();
#endif /* POINTERS_H_INCLUDED */
and modified main.cpp:
#include "helloworld.h"
#include "pointers.h"
#include <iostream>
using namespace std;
int main(){
HelloWorld();
Pointers();
return 0;
}
Now when I try to build, I get an error saying there are multiple definitions of main -- one in main.cpp, and the other in pointers.cpp.
Even more oddly, if I make a new project and do the exact same thing but reverse the order in which I create the .cpp and .h files (i.e. pointers first then helloworld), it builds and runs correctly with just the pointers files but runs into the same error when adding helloworld files, saying that the multiple exceptions of main are in main.cpp and helloworld.cpp.
I figure it must have something to do with Eclipse itself, but I don't know what the exact issue is.
Does anyone know what might be going on?
Trivial as it ought to be, I just cannot figure out how to separate my source code into different files.
My code compiles and executes just fine when it is written as a single source file:
#include <iostream>
using namespace std;
class Greeter{
public:
void greet();
};
void Greeter::greet(){
cout << "Hello World!";
}
int main(){
Greeter greeter;
greeter.greet();
return 0;
}
But try as I might, separating the code into separate source files:
Greeter.h
#include <iostream>
using namespace std;
class Greeter{
public:
Greeter();
void greet();
};
Greeter.cxx
#include <iostream>
#include "Greeter.h"
using namespace std;
void Greeter::greet(){
cout << "Hello World!";
}
main.cxx
#include <iostream>
#include "Greeter.h"
using namespace std;
int main(){
Greeter greeter;
greeter.greet();
return 0;
}
always results in a compilation error:
main.cxx:(.text+0x16): undefined reference to `Greeter::Greeter()'
It is unclear whether the comments solved your problem. In separating your source into a header and multiple sources, your primary problem evidenced by the error is that you include an incomplete constructor for class Greeter in Greeter.h. Specifically, you fail to include "an empty parameter list" to complete the constructor, e.g.
Greeter() {}; /* default construct */
See cppreference - Default constructors
The next issue you should avoid is including using namespace std; in the header file. See “using namespace” in c++ headers. Instead, simply make your call to cout, std::cout and eliminate the need to include the namespace altogether.
Next, while iostream has proper header guards, you only need to include it in Greeter.cpp (that is the only source making use of an iostream function). You should also include header guards in your Greeter.h to prevent multiple inclusions during compilation. Simply create a #define and check whether or not that is already defined within the header, e.g.
greeter.h
#ifndef my_class_greeter_h
#define my_class_greeter_h 1
class Greeter {
public:
Greeter() {}; /* default construct */
void greet();
};
#endif
Now every file that includes greeter.h will avoid including it again if my_class_greeter_h is already defined.
greeter.cpp
Your source file with your class function definition is the only source that relies on an iostream call, and is the only file that requires #include <iostream>, e.g.
#include <iostream>
#include "greeter.h"
void Greeter::greet(){
std::cout << "Hello World!\n";
}
main.cpp
You main.cpp source file need only include your header containing the class definition, e.g.
#include "greeter.h"
int main (void) {
Greeter greeter; /* instantiate greeter */
greeter.greet(); /* call greet() */
return 0;
}
Both Sources Must Be Compiled
Compiling the separate source files requires that both main.cpp and greeter.cpp be compiled (either compiling greeter.cpp to object or by simply including both .cpp files in your compile string).
Compiling With gcc/clang
$ g++ -Wall -Wextra -pedantic -std=c++11 -Ofast -o main main.cpp greeter.cpp
Compiling With VS (cl.exe)
> cl /nologo /W3 /Ox /EHsc /Femain /TP main.cpp greeter.cpp
(do not accept code until it compiles without warning)
Example Use/Output
In either case, the output is as expected:
$ ./main
Hello World!
Look things over and let me know if you have further questions.
Hi I was just trying to learn separate Classes in C++. I don't know why my code is not working.
So here is the main file code
#include <iostream>
#include "Number.h"
using namespace std;
int main()
{
Number key;
key.setNumber(200);
cout<<key.getNumber();
return 0;
}
Here is the Class cpp functions file code
#include "Number.h"
#include <iostream>
using namespace std;
void Number::setNumber(int transfernumber)
{
privatenumber = transfernumber;
}
int Number::getNumber()
{
return privatenumber;
}
And here is the header file
#ifndef NUMBER_H
#define NUMBER_H
class Number
{
public:
Number();
void setNumber(int transfernumber);
int getNumber();
private:
int privatenumber;
};
#endif // NUMBER_H
Thanks
In your cpp file you need to define the default constructor for the Number class. For example:
Number::Number() : privatenumber(0) {}
I have test your example. The error happened for the main.cpp cannot found the number.cpp. You have three ways to solve it:
write your main() to the number.cpp, not a solo file.
complie the main.cpp with the linux command gcc or write a Makefile, instead of using codeblocks.
If you want to use the codeblocks for compiling, you should create a project, and then add your three files to the project. Now compile the main.cpp.
Use the three ways above, I think you will compile successfully.
BTW, you should add the Number::Number() 's implementation.
here is the structure of my program:
// File: main.cpp
#include <iostream>
#include <math.h>
using namespace std;
#include "do.cpp"
int main()
{
doit();
}
// File: do.cpp
void doit()
{
cout<<sqrt(2)<<endl;
}
When I do
g++ main.cpp
Everything goes fine. Now, if I open this as an Xcode project (I have chosen "Command line utility" as project type) and try to just build and run, it keeps saying:
Use of undeclared identifier sqrt
Unknown type name 'ostream'
What should I be supposed to do? Did I do something wrong?
Thank you very much!
Matteo
Don't do this:
#include "do.cpp"
but instead put that "do.cpp" file in the same Xcode project, alongside your main.m or main.cpp file.
And when you want to build from the command line, you can do:
g++ main.cpp do.cpp -o mytesttool
which would create the command line tool named "mytesttool".
The explanation is quite simple actually. You probably added both files to the project. Xcode tries to compile each file into an object file and then link them together.
When it tries to compile do.cpp it doesn't find the definition of cout because iostream is not included and neither math.h for sqrt, as part of do.cpp.
That file compiles fine when compiled as part of main.cpp, because it is included in the file and it finds iostream and math.h and also the using declaration.
Anyway if you remove do.cpp from the project (just the reference) everything should compile as expected.
The right way without a header file
// File: main.cpp
void doit(); // declare the function
int main()
{
doit();
}
// File: do.cpp
#include <iostream>
#include <math.h>
using namespace std;
void doit()
{
cout<<sqrt(2)<<endl;
}
The right way with a header file
// File do.h
#ifndef __DO_H_
#define __DO_H_
void doit();
#endif // __DO_H_
// File: main.cpp
#include "do.h"
int main()
{
doit();
}
// File: do.cpp
#include <iostream>
#include <math.h>
#include "do.h"
using namespace std;
void doit()
{
cout<<sqrt(2)<<endl;
}
When making the new file, I forgot to de-check the "target" selection, so that when it tried to build the project it tried to build all the single files and then link them together. By disabling the "target", I got it to work.