How to organize includes includes in multiple Classes in C++ - c++

First I'm a beginner at programming so don't expect me to understand every code-specific word.
Second I'm sometimes slow on the uptake.
Third I think I covered the Basics of C++ but that's it. I'm happy to learn more of course!
To my Question:
I'm programming a little code to experience with classes. I made two classes, each one in a different .h and .cpp file. Now each one is using the headers iostream and string.
How should I include those without making any Problems? Is #pragma once sufficient?
Second question is about using namespace std:
where should i put it(I know it isn't a bad use but ist only for a small Programm)
First Header:
#pragma once
#include <iostream>
#include <string>
//using namespace std Nr.1
class one
{
};
Second Header:
#pragma once
#include <iostream>
#include <string>
//using namespace std Nr.2
class two
{
};
Finally Main:
#include "one.h"
#include "two.h"
//using namespace std Nr.3
int main()
{
return 1;
};
Thanks in advance for responding.

There's no problem including twice iostream and string in both class headers'.
The #pragma directive is used to protect two declarations of types (typedef, classes) of your own types.
Hence it applies to your class headers'.
Moreover, there are drawbacks using #pragma directive as stated here : https://stackoverflow.com/a/1946730/8438363
I recommend using preprocessor defines guards :
#ifndef __MY_HEADER__
#define __MY_HEADER__
//... your code here
#endif
Hope this helps.

You will need to use Include guards.They ensure the compiler includes each "included" header file(#include "XXX.h") only Once.
But if you are creating a small application & don't mind recompiling/rebuilding your entire project if need be, then putting the common header files in a dedicated header file is fair game & keeps code clean & small.

You can also make a header with all the common dependecies you need and include it in each class that needs those dependecies. Here is a simple example:
Core.h
#include <iostream>
#include <string>
// include most common headers
using namespace std;
One.h
#pragma once
#include "Core.h"
// if you need a header only for this class, put it here
// if you need a header in mutiple classes, put in Core.h
namespace one {
class One
{
public:
One();
~One();
void sumFromFirstNamespace(string firsNumber, string secondNumber)
{
//convert string to int
int first = stoi(firsNumber);
int second = stoi(secondNumber);
int result = first + second;
cout << result << endl;
}
};
}
Two.h
#pragma once
#include "Core.h"
// if you need a header only for this class, put it here
// if you need a header in mutiple classes, put in Core.h
namespace two{
class Two
{
public:
Two();
~Two();
void sumFromSecondtNamespace(string firsNumber, string secondNumber)
{
//convert string to int
int first = stoi(firsNumber);
int second = stoi(secondNumber);
int result = first + second;
cout << result << endl;
}
};
}
main.cpp
#include "One.h"
#include "Two.h"
int main()
{
one::One firstClass;
two::Two secondClass;
firstClass.sumFromFirstNamespace("10", "20");
secondClass.sumFromSecondtNamespace("20", "30");
}
There can be cases where you need the same 10+ headers in two different classes, i think that puting them in one header helps you see the code better.
And yes, preprocesor defines are also good, don't forget that. (:

Related

When I split up my C++ class into a header and implementation I get 20 compiler errors which don't make sense

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

Why are my functions undefined when I declared the type already?

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.

Invalid use of undefined type 'struct PelephonePH'

i have received in .cpp errors of invalid use of undefined struct PelephonePN, CellcomPN and so on
and also error in .h errors of forward declaration of PelephonePN,...
#ifndef PHONE_H_INCLUDED
#define PHONE_H_INCLUDED
#include <iostream>
#include <ctime>
#include <string>
#include "phone.h"
using namespace std;
class PhoneNumber;
class PelephonePN;
class CellcomPN;
class OrangePN;
class HotPN;
class BezeqPN;
class PhoneManager
{
private:
PelephonePN* mpPelephone;
CellcomPN* mpCellcom;
OrangePN* mpOrange;
HotPN* mpHot;
BezeqPN* mpBezeq;
public:
PhoneManager();
~PhoneManager();
void split_check_data(string str);
};
#endif
and .cpp
#include <iostream>
#include <ctime>
#include <string>
#include <sstream>
#include "phone_manager.h"
#include "phone.h"
using namespace std;
PhoneManager::PhoneManager()
{
srand(time(0));
mpPelephone = new PelephonePN();
mpCellcom = new CellcomPN();
mpOrange = new OrangePN();
mpHot = new HotPN();
mpBezeq = new BezeqPN();
mpPelephone->add(mpCellcom);
mpPelephone->add(mpOrange);
mpPelephone->add(mpHot);
mpPelephone->add(mpBezeq);
mpBezeq->setNext(mpPelephone);
}
To instantiate an object, forward declaration is just insufficient. Include the corresponding headers in the source file. In the body of the constructor, you are instantiating mpPelephone, ..... So, make sure that corresponding class headers can be seen in the translation unit.
In your .cpp source file you need to #include the headers that define class PelephonePN and its associates.
It is fine to forward-declare these classes in the header if you are only using them as pointers or references, but one you start using them in your implementation, you'll need to provide the compiler with the definition.
You can't use a forward declaration of a class to access its members (which includes the constructor, default or otherwise) or its size and without those two things, you can't instantiate an instance of that class.
You require its FULL implementation to do that, so in your .cpp file you need to include the header with the whole class PelephonePN {/* class body */}; section.
in the first file you have lines:
#ifndef PHONE_H_INCLUDED
#define PHONE_H_INCLUDED
I suppose you have same lines in phone.h, please check...
Are your PelephonePN and co. in a particular namespace? If so, predeclarations must all be in the same namespace. Since you added a using namespace std (sigh), my guess is that phone.h is defining your classes inside the namespace std (I hope it doesn't, but that's another thing).
If so, your predeclarations must be:
namespace std {
class PelephonePN;
}
Btw, what is a pelephone??? O.O

Problem In Separating The Interface And The Implementation

Its the first time I am trying to separate the class in a separate header file but I am getting an error.Please help me out.Thanks
CODE:
My main function:
#include <iostream>
#include <MyClass>
int MyClass::data;
int main()
{
cout<<"data="<<MyClass::data;
system("pause");
return 0;
}
MyClass.h
#ifndef MyClass
#define <MyClass>
class MyClass
{
static int data_;
};
#endif
Error: fatal error C1083: Cannot open include file: 'MyClass.h': No such file or directory
You should use
#include "MyClass.h"
angle brackets are for system headers.
Also it's data or data_?
Also it would be better something like
#if !defined(MYCLASS_H_INCLUDED)
#define MYCLASS_H_INCLUDED
...
#endif
#define-ing a name identical to the class name is going to be a source of problems
First good idea to separate definition and implementation in C++. Your #include directive shall use " and not < > as your header is not a system header. Or your header is not lying inside the same directory than the cpp file.
That is another topic but OO is more than just using some classes. Encapsulating static variables inside a class doesn't make them less global... At least they have another namespace...
use #include "Myclass.h" instead of #include

error C2039: 'string' : is not a member of 'std', header file problem

I am having problems with a class I am writing. I have split the class into a .h file that defines the class and an .cpp file that implements the class.
I receive this error in Visual Studio 2010 Express:
error C2039: 'string' : is not a member of 'std'
This is the header FMAT.h
class string;
class FMAT {
public:
FMAT();
~FMAT();
int session();
private:
int manualSession();
int autoSession();
int mode;
std::string instructionFile;
};
This is the implementation file FMAT.cpp
#include <iostream>
#include <string>
#include "FMAT.h"
FMAT::FMAT(){
std::cout << "manually (1) or instruction file (2)\n\n";
std::cin >> mode;
if(mode == 2){
std::cout << "Enter full path name of instruction file\n\n";
std::cin >> instructionFile;
}
}
int FMAT::session(){
if(mode==1){
manualSession();
}else if(mode == 2){
autoSession();
}
return 1;
}
int FMAT::manualSession(){
//more code
return 0;
}
this is the main file that uses this class
#include "FMAT.h"
int main(void)
{
FMAT fmat; //create instance of FMAT class
fmat.session(); //this will branch to auto session or manual session
}
My inability to fix this error is probably a result of me not understanding how to properly structure a class into separate files. Feel free to provide some tips on how to handle multiple files in a c++ program.
You need to have
#include <string>
in the header file too.The forward declaration on it's own doesn't do enough.
Also strongly consider header guards for your header files to avoid possible future problems as your project grows. So at the top do something like:
#ifndef THE_FILE_NAME_H
#define THE_FILE_NAME_H
/* header goes in here */
#endif
This will prevent the header file from being #included multiple times, if you don't have such a guard then you can have issues with multiple declarations.
Your FMAT.h requires a definition of std::string in order to complete the definition of class FMAT. In FMAT.cpp, you've done this by #include <string> before #include "FMAT.h". You haven't done that in your main file.
Your attempt to forward declare string was incorrect on two levels. First you need a fully qualified name, std::string. Second this works only for pointers and references, not for variables of the declared type; a forward declaration doesn't give the compiler enough information about what to embed in the class you're defining.
Take care not to include
#include <string.h>
but only
#include <string>
It took me 1 hour to find this in my code.
Hope this can help