How does chain of includes function in C++? - c++

In my first.cpp I put #include second.h.
As a consequence first.cpp sees the content of second.cpp.
In second.cpp I put #include third.h.
My question is: will first.cpp see the content of the third.cpp?
ADDED
I thought that if I include second.h I will be able to use functions declared in second.h and described (defined, written) in the second.cpp. In this sense the content of the second.cpp becomes available to the first.cpp

When using #include the actual file content of that file appears as part of the input for the compiler. This means that first.cpp will appear to the compiler as if it has second.h and third.h inside it. The source code in second.cpp and third.cpp are separate files [1], that need to be compiled separately, and they are all combined at the linking stage at the end of compilation.
[1] unless second.h contains #include "second.cpp"or something to that effect - this is not typically how to do this, however, so I'm going to ignore that option.

You can think about #include as a simple text insert. But if you include second.h you "see" second.h and not second.cpp.

With a concrete example
//second.h
#ifndef SECOND_INCLUDED
#define SECOND_INCLUDED
void foo();
#endif
//first.cpp
#include second.h
void bar()
{
foo();//ok
}
void no_good()
{
wibble();//not ok - can't see declaration from here
}
//third.h
#ifndef THIRD_INCLUDED
#define THIRD_INCLUDED
void wibble();
#endif
//second.cpp
#include second.h
#include third.h
void foo()
{
wibble();//ok in second.cpp since this includes third.h
}
The cpp file that includes a header file sees what's in the header file, not in other source files that include the header.

first.cpp will see the constent of third.h (and you will be able to use in first.cpp functions declared in third.h and defined in third.cpp). Suppose, you have in your test.h:
#include<iostream>
using namespace std;
and in your test.cpp:
#include "test.h"
int main()
{
cout << "Hello world!" << endl;
}
As you see, cout declared in <iostream> is visible in test.cpp.

Related

How to link multiple .cpp files in Code::Blocks for a single project?

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

How to use a C header.h in multiple C++ files without getting multiple definition error?

I want to use a function that from the "func.h" file in the Wireshark open source project.
I need to use the funct() function in multiple .cpp files, but I get the a multiple definition error.
func.h:
#ifndef func_h
#define func_h
#include<string>
void *funct(char *cName)
{
std::string name = cName;
cName+= ".extension";
}
In the .cpp files I include the func.h:
#include "func.h"
And call the funct() function from 2 .cpp files:
funct("program");
What should I do so I don't get the multiple definition error? A workaround is to copy and paste the function defition in every .cpp file and change the function name, but this is ugly.
Many thanks.
You have two options:
You move the implementation of the function in a separate .c/.cpp file, leaving in the header file only the declaration. Then you compile this source file, and link it with the rest of the program. Example:
func.h
#ifndef func_h
#define func_h
#include<string>
void *funct(char *cName);
#endif
func.cpp
#include "func.h"
void *funct(char *cName)
{
std::string name = cName;
cName+= ".extension";
}
You compile and link as usual, e.g.
g++ -c -o func.o func.cpp
g++ -c -o main.o main.cpp
g++ -o prog main.o func.o
You specify the keyword inline in the definition of the function. This allows appearance of the function in multiple compile units. See this question.
func.cpp:
#include "func.h"
void *funct(char *cName)
{
std::string name = cName;
cName+= ".extension";
}
func.h:
#ifndef func_h
#define func_h
#include<string>
void *funct(char *cName);
#endif
Then in your build script (CMakeLists.txt, or a simple Makefile), compile both .cpp files and link them into one executable.
You may want to put using namespace std; or using std::string; (check the latter syntax; I usually use the former), in which case you don't have to write std::.

How to divide code into multiple .cpp files C++

I want to create a function outside the main.cpp file
i've tried creating a header file but it doesn't work:
Main.cpp:
#include "other.h"
int main() {
MyFunc();
}
Other.cpp
#include <iostream>
#include "other.h"
void MyFunc() {
std::cout << "Ohai from another .cpp file!";
std::cin.get();
}
Other.h
#include <iostream>
#include "other.cpp"
void MyFunc();
nor CPP, G++, GCC compiler work
GCC Compiling error
Errors shown by vs code
You must include a header file and not a C++ file.
And therefore, you need to remove:
#include "other.cpp"
from other.h & use the following command-line for compiling:
g++ -o output main.cpp other.cpp
You'll get it linked and then compiled, then everything should be working fine.
You must remove #include "other.cpp" in header file.
erase the line "#include "other.cpp" in your other.h and you will be fine...
Edit: you also need a header guard...

How can I define my class in a different source file to my main function?

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.

Can't access function from main file from header file C++

I don't know why I can't access the function clearConsole() from my .cpp file from the header files, I guess I'm calling it wrong? How do I target the main file from a header file? I try to call the clearConsole() function after the user input in the addCustomer() functinon in customer.h.
Main.cpp
// OTS.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
using namespace std;
#include "customer.h"
// Clear function specific to Windows
// Cross platform alternatives are more convoluted to reach desired effect, so have not been included
void clearConsole()
{
#ifdef _WIN32
system("cls");
#endif
}
Customer.h
//customer.H
//The object class customer
class customer
{
//...
clearConsole();
}
If your files are linked together, a forward declaration of the functions should be enough.
Customer.h
//customer.H
//The object class customer
void clearConsole(); // <--- declare function
class customer
{
//....
};
But this structure looks wrong. I would declare the function in a different header, inside a namespace, and define it in a corresponding implementation file:
clearconsole.h
namespace ConsoleUtils
{
void clearConsole();
}
clearconsole.cpp
namespace ConsoleUtils
{
void clearConsole()
{
}
}
Move your clearConsole() method to the header file (I think is not under discussion the implementation under .header files that I actually disagree, but anyway...), and change the system message to the specific one you need, as follows:
#ifndef _WIN32
#include <syscall.h>
#endif
void clearConsole(){
#ifdef _WIN32
system("cls");
#else
system("clear");
#endif
}
I also had this problem in my kernel that I'm writing in C,C++, and Assembly. I was able to fix this problem by telling the ld command to allow shared variables and functions using the -shared flag. In gcc you would just do the same thing because gcc is a linker, assembly, c compiler and a c++ compiler.