I recently began learning C++. As a programmer coming from Python, I've noticed some general similarities when it comes to how certain things in C++ do the same thing over in Python.
One question I had is understanding Preprocessor directives. I/O Stream seems to be a common one to use in beginner programs.
Is #include effectively the same thing as import in Python, or is it completely different than importing "modules"?
C++ did not have modules until the latest standard (C++20). #include is not the same as import in the languages that support modules. Instead, it is a source code - level inclusion of a "header" file. Usually, the headers only contain declarations but not definitions of what you are "importing". The definitions are contained in compiled libraries that are added by the linker.
Congrats on diving in to C++, you're going to have many more questions and confusions coming from Python, especially if you use some of the newer standards (like C++11/14/17/20).
That aside, answering your question directly:
Is #include effectively the same thing as import in Python or is it completely different than importing "modules."
I won't speak to C++20 modules as that functionality is not fully supported across the various compilers and that is not your question. Unfortunately the answer is not a simple yes or no, it's kind of both.
In C and C++, the #include pre-processor directive essentially does a "copy-paste" of whatever file you #include before it does the compilation stage. This allows you to separate large chunks of code into easier to manage files and still reference the code in said file.
In Python/C#/Java and various other languages, you don't #include a file you want to access the classes and functions of, you import the namespace or module you wish to reference and the JIT compiler "knows" which file that module or namespace is in, allowing you to use the functionality of the code in that file.
Python and C++ don't "build" the code in the same way and thus don't reference parts of the source code in the same way.
To illustrate this point more succinctly, take the following C++ code:
file: fun.hpp
#define FUN_NUM 1
namespace fun
{
int get_fun()
{
return FUN_NUM;
}
}
file: main.cpp
#include <iostream>
#include "fun.hpp"
int main(int argc, char* argvp[])
{
if (fun::get_fun() == FUN_NUM) {
std::cout << "Fun!" << std::endl;
}
return FUN_NUM;
}
In the above code, when we #include "fun.hpp", what the C++ pre-processor does before compiling is essentially "copy-and-paste" the code in iostream and fun.hpp, so what actually gets compiled is something like the following:
file: main.cpp
// #include <iostream> <- this is replaced with the whole std::iostream file
// not putting that here as it's huge.
// #include "fun.hpp" <- this is replaced with this:
#define FUN_NUM 1
namespace fun
{
int get_fun()
{
return FUN_NUM;
}
}
int main(int argc, char* argvp[])
{
if (fun::get_fun() == FUN_NUM) {
std::cout << "Fun!" << std::endl;
}
return FUN_NUM;
}
It is because of this "copy-paste" that you also need to have include guards, because if you did something like the following:
file: main.cpp
#include <iostream>
#include "fun.hpp"
#include "fun.hpp"
int main(int argc, char* argvp[])
{
if (fun::get_fun() == FUN_NUM) {
std::cout << "Fun!" << std::endl;
}
return FUN_NUM;
}
This code won't compile because you'll get errors about various items being redeclared since what gets compiled is the following:
file: main.cpp
// #include <iostream> <- this is replaced with the whole std::iostream file
// not putting that here as it's huge.
// #include "fun.hpp" <- this is replaced with this:
#define FUN_NUM 1
namespace fun
{
int get_fun()
{
return FUN_NUM;
}
}
// #include "fun.hpp" <- this is replaced with this:
#define FUN_NUM 1
namespace fun
{
int get_fun()
{
return FUN_NUM;
}
}
int main(int argc, char* argvp[])
{
if (fun::get_fun() == FUN_NUM) {
std::cout << "Fun!" << std::endl;
}
return FUN_NUM;
}
To protect from the double inclusion and redefinition, you can simply do something like the following:
file: fun.hpp
#if !defined(FUN_HPP)
#define FUN_HPP
#define FUN_NUM 1
namespace fun
{
int get_fun()
{
return FUN_NUM;
}
}
#endif // define FUN_HPP
So unless you pass FUN_HPP as a pre-processor define to the compiler, then FUN_HPP will not be defined until the file is #include'd once, then any other times it's included, FUN_HPP will already be defined and thus the pre-processor will not include the code again, ridding the problem of double-definitions.
So where your question is concerned, the #include directive in C++ is somewhat like the import directive in Python, but mostly to the effect that they both allow the file you are putting that directive in, to access code more directly from that import or #include.
I hope that can add a little clarity.
Related
I've been puzzled by this for a while. To test this out, I made a simple program that just creates a std::string variable and prints it out to the screen. However, it doesn't include <string.h>.
#include <iostream>
using namespace std;
int main()
{
string name = "Test";
cout << name << endl;
return 0;
}
What confuses me is that this program compiles and runs perfectly. Right now I'm using the clang compiler that came with the XCode Developer Tools. Is this intended behavior? I hope this question isn't too ridiculous since I just started learning C++.
The reason you do not need to include the #include <string.h> header file is because when you include the #include <iostream> header file it includes std::string.
However, do not rely on it. What may work on your compiler may not work on another. Always include the proper header files.
To edit your example this is how you should use it:
#include <iostream>
#include <string>
int main()
{
std::string name = "Test";
std::cout << name << std::endl;
return 0;
}
Also note: why you should not use using namespace std;.
Why does my program compile successfully if I don't include <string.h>?
Because you don't use any definition / declaration from <string.h>.
program compiles and runs perfectly ... Is this intended behavior?
It is incidental behaviour.
There are no guarantees that one standard header wouldn't include other standard headers. It just so happens that <iostream> included <string> in this particular version of the standard library. Since there is no guarantee for this, it would be a mistake to rely on such transitive inclusion.
I was splitting up my program into a header and implementation file per usual, however, when I tried to run the code, I got a ton of compile errors. This seems to be an issue with my computer or IDE, but I have not seen it before. This should be relatively simple as it is for a class project.
The code is as follows:
colorPicker.h
#pragma once
class colorPicker {
private:
string colorArray[7];
public:
colorPicker();
void printAllColors();
string randomColor();
};
colorPicker.cpp
#include "colorPicker.h"
#include "stdafx.h"
#include <iostream>
#include <string>
#include <ctime>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
colorPicker::colorPicker() {
colorArray[0] = "Red";
colorArray[1] = "Green";
colorArray[2] = "Purple";
colorArray[3] = "Yellow";
colorArray[4] = "Orange";
colorArray[5] = "Indigo";
colorArray[6] = "Pink";
}
void colorPicker::printAllColors() {
for (int i = 0; i < 7; i++) {
cout << colorArray[i] << endl;
}
}
string colorPicker::randomColor() {
srand((unsigned)time(0));
int j = 0;
j = rand() % 7;
return colorArray[j];
}
main.cpp
#include "colorPicker.h"
#include "stdafx.h"
#include <iostream>
#include <string>
#include <ctime>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int main() {
colorPicker p;
p.printAllColors();
cout << "Random Color: " << p.randomColor() << endl;
system("pause");
return 0;
}
There are 20 errors given by the compiler, however, they all seem to be stemming from two undeclared identifiers which are most definitely declared. I am at a loss for what I could possibly do to fix it, and this project is due Sunday. Thank you.
Here are the errors
Tons of Errors
You need #include "colorPicker.h" in colorPicker.cpp. Each .cpp file is handled basically independently by the compiler and they are all joined at the end by the "linker." When the compiler looks at colorPicker.cpp without an include of the corresponding header, it's at a loss as to the definition of all the classes you're working with.
There are a few things you are doing wrong. I'll just pick on a couple.
Firstly, each header file you write should be self-contained - in the sense that, if it relies on content of some other headers, it includes that header. If a compilation unit (a formal name for a source file with a .cpp in your case) includes your header, it should not have to include something else your header depends on.
Second, it is a bad idea for a header to rely on any using directive, such as using namespace std. There are plenty of explanations of that available, so I won't repeat.
To understand the above, look at colorPicker.h
class colorPicker {
private:
string colorArray[7];
public:
colorPicker();
void printAllColors();
string randomColor();
};
Firstly, this depends on string, but there is no definition of string visible in the header file. Usage of that type depends on the standard header <string>.
Second, that string type is within namespace std. So your header relies on the compilation unit (the source file that includes your header) having previously used a using directive i.e. using namespace std.
To fix these two problems, change the header to
#ifndef SOME_MACRO_UNIQUE_TO_YOUR_COLOR_PICKER_HEADER
#define SOME_MACRO_UNIQUE_TO_YOUR_COLOR_PICKER_HEADER
#include <string>
class colorPicker
{
private:
std::string colorArray[7];
public:
colorPicker();
void printAllColors();
std::string randomColor();
};
#endif
(I've also done some minor changes of layout, since I have various reasons to prefer that.
However, the #include <string> means that this version will not fail to compile, as yours does, if it is included by a compilation unit that does not have #include <string>.
The usage of the fully qualified name std::string, rather than string, also means there is no dependence on the using directive using namespace std. It also means compilation errors can't be triggered in your header if your compilation unit has another using directive.
I've also used an include guard, rather than #pragma once. Although most modern compilers support #pragma once, it is actually not standard C++ (a #pragma, by definition in the standard, is a compiler-specific hook). Include guards are supported in standard C++.
If you've done that, your code should mostly compile as is. However, optionally, you may wish to
remove the using directives using namespace std from your other files. If you do that, you will need to change the definition of colorPicker::randomColor() in colorPicker.cpp so it returns the fully qualified type std::string rather than string.
Remove #include <string> from files that have #include "colorPicker.h". This is possible, since colorPicker.h now includes <string>. This step is optional, since there is no problem with including standard headers more than once in a compilation unit.
A few other notes
In C++, although it is not a major concern, it is usually considered better to use include <cstdio> and <cstdlib> rather than the C headers <stdio.h> and <stdlib.h>.
Your code is calling srand((unsigned)time(0)) whenever colorPicker::randomColor() is called. It is better to only call it once in an entire program, not in a function that may be called multiple times.
A header file should be self-contained as far as #includes go. That means that you should be able to #include the header file without having to include other stuff before it!
Your colorPicker.h does not meet that requirement. It apparently uses std::string from the standard library but does not have an #include <string> on top, so everyone who uses colorPicker.h has to remember to put an #include <string> before it. That's pretty annoying.
Even worse, colorPicker.h refers to std::string as string, which implies a using std::string; or using namespace std; somewhere before any #include "colorPicker.h" line, and both of those are very bad coding style in C++, if not used in tighter scopes.
Here's how to fix the header file:
#pragma once
#include <string>
class colorPicker {
private:
std::string colorArray[7];
public:
colorPicker();
void printAllColors();
std::string randomColor();
};
As far as your *.cpp files go, I can see that you are using #include "stdafx.h". Why? It's a non-standard Microsoft thing completely unnecessary in your case. You are also using it incorrectly. It must be the first include. Just remove it entirely.
Some other suggested cleanup:
using namespace std; lines in *.cpp files is not as bad as in header files, but if I were you, I'd just get rid of it completely. Just use complete names. Say std::cout, not cout. And so on. It's just the most consistent way and it avoids a lot of trouble.
You include a lot of headers which you don't need. For example, what's <ctime> for?
Don't use system("pause");. Do not look for artificial ways of pausing a command-line program.
You may need add head file and in colorPicker.h.
And the std namespace is needed while using string.
BTW, the header guards is recommended strongly.
#ifndef COLOR_PICKER_H
#define COLOR_PICKER_H
#pragma once
#include <string>
class colorPicker {
private:
std::string colorArray[7];
public:
colorPicker();
void printAllColors();
std::string randomColor();
};
#endif
All I'm trying to do is create a separate class to hold my Hello World function (this is for a class), but I am getting an "identifier is undefined" compiler error. What is the issue?
Here is my main function (helloworld.cpp):
#include <iostream>
using namespace std;
int main() {
print_me();
system("pause");
return 0;
}
And here is the header class (helloworld.h) :
#include <iostream>
void print_me() {
std::cout << "Hello World\n";
}
You have not included helloworld.h in helloworld.cpp. The following code should work:
#include <iostream>
#include "helloworld.h"
using namespace std;
int main() {
print_me();
system("pause");
return 0;
}
One thing to remember is from your compiler's point of view, there is no connection between the two files unless you specify it. The fact that both files have the same name does not have any significance for compiler.
Side note 1: Consider using include guards in your header files. For simple projects, it may not be obviously necessary but for larger projects, not using them can lead to annoying ambiguous compilation errors.
Side note 2: Implementing function bodies in header files is generally discouraged.
Since the namespace std already has the c++ libraries that contain the function definitions(if i am right), then why do we include header files on top of it??. Since namespace std includes the c++ standard libraries, I don't see a reason to include the declarations of it separately.
When you do #include <iostream> it causes a set of classes and other things to be included in your source file. For iostream, and most of the standard library headers, they place these things in a namespace named std.
So the code for #include <iostream> looks something like this:
namespace std {
class cin { ... };
class cout { ... };
class cerr { ... };
class clog { ... };
...
}
So at this point, you could write a program that looks like:
#include <iostream>
int main() {
std::cout << "hello\n";
return 0;
}
Now, some people feel that std::cout is too verbose. So they do:
#include <iostream>
using namespace std;
int main() {
cout << "hello\n";
return 0;
}
Personally, I'd recommend against this, and if you really feel that std::cout is too verbose, then I'd suggest that you use a smaller using statement.
#include <iostream>
using std::cout;
int main() {
cout << "hello\n";
return 0;
}
If you're wondering why I would recommend against using namespace std, then I would forward you to the following two other posts on stackoverflow:
C++ Distance Function Keeps Returning -1
Why is "using namespace std" considered bad practice?
The compiler itself does not have the definitions of the things that are in any namespace (whether it is std or some other namespace). That is the role of source files and header files.
What using namespace std; tells the compiler is that "If you can't find some name in the current namespace, go look in the std namespace as well".
What #include <iostream> tells the compiler is that you want the contents of the header called iostream to be included in your sources. This will provide the compiler with code to do cin, cout and a lot of other related functionality. The content of this file is declared like namespace std { ... all the stuff goes here ... }.
The usage of namespace allows someone else, working in namespace math; to not have to worry about "Hmm, what do I do now, I need a counter for number of entrances, let's call it cin - but hang on, is that ever used anywhere?".
This may not be the greatest of examples, but in large projects, it gets increasingly hard to keep track of things and what names they have. And C++ is a language intended for large projects of millions of lines of code - and now it starts getting hard to remember if you've used a particular name or not. Namespaces make sure that you don't have to worry about it outside of a particular namespace.
(Oh, and in my code, I tend to not use using namespace std;, but write std::cout << "Hello, World!" << std::endl; - this helps to make it clear that the cout I'm using here is the std one, and not something else. This is particularly useful when you have several namespaces with similar things, like in my own compiler, where I have my compiler with it's functionality, the std namespace providing some things, and llvm compiler things - if I were to stick using namespace llvm; at the beginning of the code, it would be very hard to track whether Type* p = ...; is from LLVM or some part of my own code.)
...why do we include header files on top of it???
Yes, there is some big confusion here.
Namespaces
Namespaces are a method to categorize or group together, symbols such as function names.
Namespaces are design to prevent name conflicts between different software components, such as libraries.
Functions that are a part of the standard language, are grouped under the namespace std.
The C++ language provides statements to reduce the amount of typing when using namespaces. One of these is the using statement.
Header (include) Files
When you write a program, the compiler is not required to automatically include all the symbol definitions, such a function declarations. You need to tell it which functions you plan on using.
For example, I could write a program without using the sort or advance functions from the algorithm group. Therefore I would not include the header file algorithm.
The C++ language is designed to be "use what you need", in other words, we can create small programs by only including the functions we need.
Other Platforms
By the way, there are many other platforms out there than the one you are using.
Some platforms need to fit in small memory areas and may not have a keyboard or display (such as embedded controllers).
So remember, C++ was defined to support platforms from the small and constrained to the large and virtually unconstrained system.
Thus the requirement to "include only what you need" theme.
Summary
In summary, since the C++ languages doesn't automatically, magically, provide the definitions of the entire library, including the template library, you need to tell the compiler which groups of functions you want to use. This allows for quicker compilations since only the required header files are specified.
Note: Some shops and library supplies like to use the Monolith include system. This means that they have one include file that includes their entire library, whether you use one function or many. The windows.h is a classic example. One detriment is that when one header file is changed, everything needs to be rebuilt. With separated include files, only the components that include the changed header file need to be rebuilt.
Use of preprocessor directive #include is as old as c++ itself. And its not going away any sooner.In C++ namespace Doesn't import anything into your program, it just defines the scope of your particular header file's function.So, both are required. Click hereto understand why use namespace.
Your question is: namespace std has all the definitions of functions/classes of iostream library. So simply using using namespace std is enough to call or use cout or all other functionalities of iostream library. Why do we have to use line #include <iostream>? It seems redundant.
Roughly we can think that iostream library has two files: header and implementation/source file. These two files have a namespace called std. The header file only contains the declarations or forward declarations of classes or functions or variables that iostream library is going to use and these declarations or forward declarations are under the std namespace. The implementation file contains the actual implementations of the classes or functions or variables and these implementations are under the std namespace; this file is also called the source file.
So if you only use using namespace std without #include <iostream> in your main.cpp file compiler will search std namespace in your main.cpp file, but it is not here. You will get compiler error.
Now if you include this #include <iostream> line in your main.cpp, preprocessor will go iostream's header file and copy the std namespace along with its code into our main.cpp. And linker will link the precompiled(as iostream is a SLT so it comes with compiler with prebuilt) source/implementation file of iostream to your main.cpp. Now to use functions or variables of iostream that sit under std namespace in main.cpp we have to use scope resolution operator(::) to tell the compiler that cout, cin and other functionalities of iostream sit at std namespace. Thus we simply write like this: std::cin, and std::cout.
Now typing std:: seems redundant to some people so they tell the compiler by using this using namespace std "Hey compiler, if you don't find any variables/functions/classes in global/current namespace go look in the std namespace." Though this is not the best practice but that is another topic to discuss. Therefore your assumption that std namespace contains all the definitions of all SLT's functions/classes/variables of C++ is not correct in most cases, but std namespace only contains the declaration from STL is the correct assumption.
Here is a dummy implementation how iostream libray is added to our code files:
iostream.h:
// This is header file that only contains the
// functions declarations.
namespace std_dum
{
int add(int x, int y);
int mult(int x, int y);
}
iostream_dum.cpp:
// This is source file of iostream_dum.h header
// which contains the implementation of functions.
#include "iostream_dum.h"
namespace std_dum
{
int add(int x, int y)
{
return x + y;
}
int mult(int x, int y)
{
return x * y;
}
}
main.cpp :
#include <iostream>
#include "iostream_dum.h"
int main()
{
std::cout << std_dum::add(100, 200) << '\n';
std::cout << std_dum::mult(100, 200) << '\n';
return 0;
}
To see what happens to our main.cpp file after preprocessing run this command: g++ -E main.cpp iostream_dum.cpp.
Here is roughly our main.cpp looks like:
namespace std_dum
{
int add(int x, int y);
int mult(int x, int y);
}
int main()
{
std::cout << std_dum::add(100, 200) << '\n';
std::cout << std_dum::mult(100, 200) << '\n';
return 0;
}
namespace std_dum
{
int add(int x, int y)
{
return x + y;
}
int mult(int x, int y)
{
return x * y;
}
}
For the sake of clarity, I discarded all the codes that the preprocessor copied from #include <iostream>.
Now it should be pretty clear.
I'm working on making a game in C++. I have declared a Constant namespace used for global values that I need access to throughout the program. In there I have an ofstream for debugging purposes (yeah, I know it's not "constant" but it fits best there), which outputs only when it feels like it. I was able to make a small program demonstrating the problem. I apologize for it being spread across 4 files, but it is important, I promise.
main.cpp:
// Include necessary files
#include "test.h"
#include "constants.h"
#include <fstream>
using namespace std;
int main(int argc, char* argv[])
{
// Start of program
Constant::outstream.open("test.txt");
// ...
// Do stuff
// Output debugging info
Test test;
test.print("Test", Constant::outstream);
// ...
// Do other stuff
// End of program
Constant::outstream.close();
return 0;
}
constants.h:
#ifndef _CONSTANTS_H
#define _CONSTANTS_H
#include <fstream>
namespace Constant
{
static ofstream outstream;
}
#endif
test.h:
#ifndef _TEST_H
#define _TEST_H
#include <string>
#include <fstream>
#include "constants.h"
class Test
{
public:
void print(string str, ofstream& out);
};
#endif
test.cpp:
#include "test.h"
using namespace std;
void Test::print(string str, ofstream& out)
{
out << "out: " << str << endl << flush; // Works
Constant::outstream << "Constant::outstream: " << str << endl << flush; // Doesn't
}
In the test.cpp file, the out << ... line works as it should, while the Constant::outsream << ... line doesn't do anything even though I'm passing Constant::outstream as the out parameter! I don't see any reason why these two lines should be in any way different.
Before posting this, I tried putting test.cpp's code in test.h, just to have less files for the question, and was amazed to see it work. If I copy-paste the Test::print() function into test.h (whether inside or out of the class Test { ... }), then both output commands work correctly. the problem only occurs if Test::print()'s implementation is in a separate file.
It seems like any references to Constant::outstream simply don't work in class cpp files (no compile error, just nothing happens). It works in main.cpp and in class header files, but any class cpp file it seems not to. Unfortunately, this is a big program I'm writing so pretty much every class has its own cpp implementation file, and that's really the one place I need to use this ofstream. Does anyone know the reason for this?
Thanks in advance,
Doug
Constant::outstream has internal linkage, thus a separate instance is created for each translation unit. In short, Constant::outstream in test.cpp and main.cpp are two different variables.
§3.5.2 A name having namespace scope (3.3.6) has internal linkage if it is the name of
— a variable, function or function template that is explicitly declared static; or,
On the other hand, static class members would be visible throughout the program.
So, if you would write
struct Constant
{
static ofstream outstream;
}
instead of
namespace Constant
{
static ofstream outstream;
}
it would work.
However, note that the class must have external linkage; e.g. you should not put in in anonymous namespace.