What is the difference between these two headers? - c++

I have these two header files and one produces an error if I don't put std:: in front of all string declarations and the other doesn't. I was just wondering what the difference between the two was.
The following will produce an error if the std:: is not in front of the string declarations:
#include <string>
#include <vector>
#pragma once
#ifndef DATABASE_H
#define DATABASE_H
struct Item
{
public:
std::string object;
int numOfColors;
std::string colors;
int sizeSmall;
int sizeLarge;
};
class database
{
private:
void fillDatabase(std::vector<Item>);
public:
void getDatabase(std::vector<Item>);
};
#endif
The following code will not produce an error:
#include <string>
#pragma once
#ifndef GUISTRUCT_H
#define GUISTRUCT_H
struct guiValues
{
public:
string shape;
string color;
int width;
double squareProbability;
double rectangleProbability;
double circleProbability;
string firstMostLikelyObject;
double FMLOprobability;
string secondMostLikelyObject;
double SMLOprobability;
string thirdMostLikelyObject;
double TMLOprobability;
};
#endif

The second file is included after some other that defines
using namespace std;

string is declared in the namespace std. So one needs to use the namespace std to make use of string. it can be done in two ways:
By explicitly mentioning which type(string in this case) you want to include from the std namespace as in case 1, std::string colors
OR
By enabling the entire std namespace, using namespace std; which imports all types from the namespace in your global namespace.(Please note that Doing this in headers is not recommended)
In the second case seems you have included the entire std namespace before the particular include and hence it is not giving an error even without exlpicit mention of std::String

Related

C++, Linking a locally defined struct to external function

I'm being tasked with defining a struct within my main() function, but using it in other files. I have the code working if I define my struct inside my header file, but I cannot figure out how to define struct inside main() and still use it outside its given scope.
Example of what I have now:
3 files: main.cpp, header.h, and function.cpp
main.cpp
#include <iostream>
#include "header.h"
using namespace std;
int main()
{
vector<myStruct> myVec;
myFunction(myVec);
return 0;
}
header.h
#ifndef HEADER_H_INCLUDED
#define HEADER_H_INCLUDED
#include <vector>
using namespace std;
struct myStruct{
int typeInt;
string typeString;
double typeDouble;
};
void myFunction(vector<myStruct>&);
#endif // HEADER_H_INCLUDED
function.cpp
#include <iostream>
#include <vector>
#include "header.h"
using namespace std;
void myFunction(vector<myStruct>& myVec){
myVec.push_back(myStruct());
myVec[0].typeInt=5;
cout<<myVec[0].typeInt<<endl;
}
Right now, this works for what I need it to do. Unfortunately, I'm told I cannot define struct myStruct inside header.h but instead must have it within main() in main.cpp.
I've tried changing my code to the following (function.cpp unchanged):
main.cpp v2
#include <iostream>
#include "header.h"
using namespace std;
int main()
{
struct myStruct{
int typeInt;
string typeString;
double typeDouble;
};
vector<myStruct> myVec;
myFunction(myVec);
return 0;
}
header.h v2
#ifndef HEADER_H_INCLUDED
#define HEADER_H_INCLUDED
#include <vector>
using namespace std;
template <typename myStruct>
void myFunction(vector<myStruct>&);
#endif // HEADER_H_INCLUDED
Now I receive the error:
error: 'myStruct' was not declared in this scope on line 7 of function.cpp.
How can I use myStruct in function.cpp, while still defining myStruct in main() of main.cpp?
this way using template is correct, that problem occur in function.cpp right?
you try to define the function "myFunction(..)" in header.h,
and remove function.cpp, this program will work well.
if you must implement that fuction in function.cpp, you have to create a template class.

Order of header file inclusions and dependencies

I'm just trying to test splitting code into multiple files.
I have:
//testMultiple.cpp
#include <string>
#include <iostream>
#include "testInclude.cpp"
int main(){
std::cout << "hi";
}
and
//testInclude.cpp
class testClass{
public:
string x;
};
This is giving testInclude.cpp:3:9: error: ‘string’ does not name a type
I thought since it was including before it included the testInclude.cpp, string would be defined for use in testInclude.cpp.
You need to use std::string instead of string.
You're including a cpp file, not a hpp file.
Common practice is to include header (h/hpp) files, not implementation (c/cpp) files.
If you only compile testMultiple.cpp, this should work. If the compiler is compiling testInclude.cpp separately, it will not see the `#include
Try renaming testInclude.cpp to testInclude.hpp and ensure it is not being compiled.
Here's an example:
///// testInclude.h
#include <vector>
class testClass{
public:
std::vector<int> x; // vector is in std namespace
};
///// testMultiple.cpp
// #include <vector> - gets this through testInclude.h
#include "testInclude.h"
int main(){
}
Use
class testClass{
public:
std::string x;
};

Redefinition of class

I got three .cpp files and two header files.
But when i compile them, meaning the Point.cpp, Data.cpp and main.cpp, it will say
Data.h:6:7 redefinition of Data at 'Data.h'
Data.h:6:7 previously definition of 'class Data'
Below is my Data.h(previously known as 2.h at above)
#include <iostream>
#include <string>
using namespace std;
class Data
{
private:
string sType;
public:
Data();
Data(string);
void setSType(string);
string getSType();
};
Below is my data.cpp
#include "Data.h"
Data::Data()
{
sType = "";
}
Data::Data(string s)
{
sType = s;
}
void Data::setSType(string ss)
{
sType = ss;
}
string Data::getSType()
{
return sType;
}
Below is my PointD.h (previously known as 3.h)
#include <iostream>
#include <string>
#include "Data.h"
using namespace std;
class PointD
{
private:
int x
Data data1;
public:
PointD();
PointD(int,Data);
void setX(int);
void setData(Data);
int getX();
Data getData();
};
Below is my PointD.cpp
#include "PointD.h"
PointD::PointD()
{
x = 0;
}
PointD::PointD(int xOrdinate,Data dd)
{
x = xOrdinate;
data1 = dd;
}
void PointD::setXordinate(int Xordinate)
{
x = Xordinate;
}
void PointD::setData(Data dd)
{
data1 = dd;
};
int PointD::getXordinate()
{
return x;
}
Data PointD::getData()
{
return data1;
}
This is my main.cpp
#include <iostream>
#include <string>
#include "Data.h"
#include "PointD.h"
using namespace std;
int main()
{
const int MAX_NUM = 20;
Data ldata[MAX_NUM];
PointD pointd[MAX_NUM];
//more codes..
}
But when i compile them, meaning the Point.cpp, Data.cpp and main.cpp, it will say
Data.h:6:7 redefinition of Data at 'Data.h'
Data.h:6:7 previously definition of 'class Data'
Can anybody let me know whats actually went wrong here..
You need to use include guards, or the easiest:
#pragma once
in your header files
See Purpose of Header guards for more background
Idea: 1.hpp
#ifndef HEADER_GUARD_H1_HPP__
#define HEADER_GUARD_H1_HPP__
// proceed to declare ClassOne
#endif // HEADER_GUARD_H1_HPP__
In each of your header files write:
#ifndef MYHEADERNAME_H
#define MYHEADERNAME_H
code goes here....
#endif
Its better like this:
#ifndef DATA_H /* Added */
#define DATA_H /* Added */
#include <iostream>
#include <string>
// using namespace std; /* Removed */
class Data
{
private:
std::string sType;
public:
Data();
Data( std::string const& ); // Prevent copy of string object.
void setSType( std::string& ); // Prevent copy of string object.
std::string const& getSType() const; // prevent copy on return
std::string& getSType(); // prevent copy on return
};
#endif /* DATA_H */
The big fix is adding ifndef,define,endif. The #include directive works as if copying and pasting the .h to that line. In your case the include from main.cpp are:
main.cpp
-> Data.h (1)
-> Point.h
-> Data.h (2)
At (2), Data.h has already been `pasted' into main.cpp at (1). The class declaration of Data, i.e. "class Data{ .... };" , appears twice. This is an error.
Adding include guards to the top and bottom of every .h are standard practice to avoid this problem. Don't think about it. Just do it.
Another change I'd suggest is to remove any "using namespace ..." lines from any .h . This breaks the purpose of namespaces, which is to place names into separate groups so that they are not ambiguous in cases where someone else wants an object or function with the same name. This is not an error in your program, but is an error waiting to happen.
For example, if we have:
xstring.h:
namespace xnames
{
class string
{
...
};
}
Foo.h
#include <xstring>
using namespace xnames;
...
test.cxx:
#include "Foo.h"
#include "Data.h" // Breaks at: Data( string ); -- std::string or xnames::string?
...
void test()
{
string x; // Breaks. // std::string or xnames::string?
}
Here the compiler no longer knows whether you mean xnames::string or std::string. This fails in test.cxx, which is fixable by being more specific:
void test()
{
std::string x;
}
However, this compilation still now breaks in Data.h. Therefore, if you provide that header file to someone, there will be cases when it is incompatible with their code and only fixable by changing your header files and removing the "using namespace ...;" lines.
Again, this is just good coding style. Don't think about it. Just do it.
Also, in my version of Data.h, I've changed the method parameters and return types to be references (with the &). This prevents the object and all of its state from being copied. Some clever-clogs will point our that the string class's is implementation prevents this by being copy-on-write. Maybe so, but in general, use references when passing or returning objects. It just better coding style. Get in the habit of doing it.

expected class name before '{' token. C++ inheritance

I've spent quite a few hours researching and trying to figure out why I'm getting this error. Basically the three files that have to do with the inheriting are CollegeMember.h, Employee.h, and EmpAcademicRecord.h. Employee. is inheriting from CollegeMember.h and EmpAcademicRecord.h is inheriting from Employee.h. Like this CollegeMember <- Employee <- EmpAcademicRecord. The error occurs in EmpAcademicRecord.h. Heres the three files.
CollegeMember.h
#include <cstdlib>
#include <iostream>
#include<ctype.h>
#include<string.h>
#include "Employee.h"
#include "Student.h"
using namespace std;
// ****************************************************************************
// Class Definitions follow
typedef char* String;
// The CollegeMember class
class CollegeMember
{
protected:
int ID_Number;
string FirstName, LastName;
string AddressLine1, AddressLine2, StateProv, Zip;
string Telephone;
string E_Mail;
string answer, answer2, answer3, answer4;//used as sort of booleans for use with validation
// member functions
public:
CollegeMember ( ); // constructor
CollegeMember(const CollegeMember&); //overloaded constructor
void Modify (CollegeMember Member);
void InputData(int x);
string Summary ( ); //summary
string PrintMe(); //fully describes
}; // End of CollegeMember class declaration
Employee.h
#include <cstdlib>
#include <iostream>
#include<ctype.h>
#include<string.h>
#include "EmpAcademicRecord.h"
#include "EmpEmploymentHistory.h"
#include "EmpExtraCurricular.h"
#include "EmpPersonalInfo.h"
#include "EmpPublicationLog.h"
using namespace std;
// ****************************************************************************
// Class Definitions follow
typedef char* String;
// The Employee Class
class Employee: protected CollegeMember
{
float Salary;
protected:
string Department, JobTitle;
// Member Functions
public:
Employee ( ); // constructor
void Modify (Employee ThisEmp);
void InputData(int x);
void SetSalary (float Sal) // Specified as an in-line function
{ Salary = Sal;}
float GetSalary ( ) {return Salary;} // Specified as an in-line function
string Summary ( ); //summary
string PrintMe(); //fully describes
}; // End of Employee class declaration
EmpAcademicRecord.h
#include <iostream>
#include <cstdlib>
#include<ctype.h>
#include<string.h>
using namespace std;
typedef char* String;
class EmpAcademicRecord: protected Employee{ //error occurs on this line
protected:
int ReferenceNumber;
string Institution;
string Award;
string start;
string end;
public:
EmpAcademicRecord();
void InputData (int x);
void Modify(EmpAcademicRecord ThisRec);
void Summary();
};
Any help with this would be greatly appreciated.
That sort of error is usually caused by the type not being defined when you try to use it.
In this case, it appears that you may have included EmpAcademicRecord.h without having first included Employee.h (the includes at the top of the former do not show the latter).
In other words, at the point where the compiler sees:
class EmpAcademicRecord: protected Employee { //error occurs on this line
it has no idea what the Employee class is.
It may be a simple matter of adding:
#include "Employee.h"
to the top of that file, it's a little difficult to be certain since we don't have the code files. In any case, it's certainly a good first step.
Since you have EmpAcademicRecord.h being included by Employee.h, that will probably result in an infinite recursion.
You could fix that with include guards, but I can't see why you need that particulat inclusion. EmpAcademicRecord depends on Employee, not the other way around.

Class two has no member v error

I am new to C++ and I have a problem.I am trying to make to classes mutual friend,and accessing different members in one from the other one.I can't figure out what is that I do wrong.Here is what I have so far:
#ifndef HA_H_
#define HA_H_
#include"Ha2.h"
using namespace std;
class two;
class one{
public:
int tip;
int timp;
one(int t) :tip(t){}
friend class two;
};
#endif /* HA_H_ */
The second header:
#ifndef HA2_H_
#define HA2_H_
#include"Ha.h"
#include<vector>
class one;
class two{
public:
vector<one> v;
vector<int> x;
inline void create_x(vector<one> v){
// vector<one>::iterator it=v.begin();
int i;
for(i=0;i<v.size();i++){
x.push_back(v.at(i).tip);
}
}
friend class one;
};
#endif /* HA2_H_ */
And the main:
#include<vector>
#include<iostream>
#include"Ha.h"
#include"Ha2.h"
int main()
{
one o(3);
two x;
x.v.push_back(o);
x.create_x(x.v);
cout<< x.x.back();
}
And I get several errors like:
class two has no member named 'v'
Any advice?Thank you.
main.cpp includes "Ha.h", which, before using namespace std;, includes "Ha2.h". Then, class two is defined, which declares v as a vector<one> without qualifying vector in the std namespace.
There is no need to include "Ha2.h" in "Ha.h", remove that, then qualify vector.
Forward declarations are used when the class definition has pointers or references. And neither of the class definitions has them and so forward declarations are unnecessary.
Also the headers has both forward declarations and it's corresponding header inclusion which voids the whole purpose of forward declarations.
Include the headers and also the using directive in the source files.
As of now, the program has no methods to test the purpose of friend and so this should at least make the program compile.
Ha.h header :
#ifndef HA_H_
#define HA_H_
class two ; // No pointers or references of two in one.
// So, remove it and place when you actually have
// a method taking reference of two.
class one{
public:
int tip;
int timp;
one(int t) :tip(t){}
friend class two;
};
#endif /* HA_H_ */
Ha.cpp
#include "Ha2.h" // Place this only when have a method accessing
// members of two. Else this is unnecessary.
#include "Ha.h"
using namespace std ;
Ha2.h
#ifndef HA2_H_
#define HA2_H_
class one ; // No pointers or references of one in two.
// So, remove it and place when you actually have
// a method taking reference of one.
class two{
public:
vector<one> v;
vector<int> x;
inline void create_x(vector<one> v)
{
// vector<one>::iterator it=v.begin();
int i;
for(i=0;i<v.size();i++)
{
x.push_back(v.at(i).tip);
}
}
friend class one;
};
#endif /* HA2_H_ */
Ha2.cpp
#include <vector>
#include "Ha.h" // Place this only when have a method accessing
// members of two. Else this is unnecessary.
#include "Ha2.h"
using namespace std ;
// .....
main.cpp
#include <vector> // Definitely need this because in the current unit, Ha2.h is
// included which has a data type of vector<int>
#include <iostream>
#include"Ha.h"
#include"Ha2.h"
using namespace std ; // vector and the other standard definitions are specified
// in std namespace
int main()
{
one o(3);
two x;
x.v.push_back(o);
x.create_x(x.v);
cout<< x.x.back();
}
With the above modifications, you should get rid of errors. If any new errors pop up, post the exact error messages in your question.
Another alternative to remove the circular dependency is to make a separate header file, like decl.h or whatever you want it to be, and inside of that simply put the following lines:
#ifndef DECL_H_
#define DECL_H_
class one;
class two;
#endif DECL_H_
Then in Ha.h and Ha2.h remove the #include "Ha.h" and #include "Ha2.h" lines and replace them with #include "decl.h". Also remove the class one; and class two; declarations in Ha.h and Ha2.h, but keep the definitions of each respective class.
Now you won't have Ha.h depending on Ha2.h and vice versa.
Hope this helps,
Jason