how to wrap several files into the same namespace in C++ - c++

In C# it's simple to put all of the classes into an unique namespace. I understand how a namespace works in C++ at a simple level. But when comes to put many files together to appear as one namespace I get really confused.
It is something like this possible:
/* NetTools.cpp
blade 7/12/2014 */
using namespace std;
using namespace NetTools;
#include "NetTools.h"
int main()
{
cout << "testing" << endl;
return 0;
}
//####### EOF
/* NetTools.h
blade 12/7/2014 */
#ifndef NETTOOLS_H
#define NETTOOLS_H
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
namespace NetTools
{
}
#endif
// #### EOF
/* Commands.h
blade 7/12/2014 */
#include "NetTools.h"
#ifndef COMMANDS_H
#define COMMANDS_H
namespace NetTools
{
}
#endif
// ###### EOF
I'm separating every class declaration in its .h file and the implementation in its cpp file, but I want everything to be in the same namespace.

What you've shown works fine.
One fundamental property of namespaces is that if different files all declare things in a namespace with the same name, the compiler/linker know to put things together so you get one namespace containing everything that was defined in it from all the files.
For example:
// file a
namespace A {
class X;
}
// file b
namespace A {
class Y;
}
// file c
namespace A {
class Z;
}
...is mostly equivalent to:
// one file
namespace A {
class X;
class Y;
class Z;
}
The exception to this is anonymous namespaces. Anonymous namespaces are separated per-file. For example:
// file a
namespace {
void f();
}
// file b
namespace {
int f();
}
These don't conflict because each file has its own, unique anonymous namespace.

What you are doing is correct. There is a problem with your code here though:
/* NetTools.cpp
blade 7/12/2014 */
using namespace std;
using namespace NetTools; // put this AFTER #include "NetTools.h"
#include "NetTools.h"
int main()
{
cout << "testing" << endl;
return 0;
}
It works for using namespace std; (not sure why) but it won't work for namespaces you declare. The compiler needs to see them before you can start using them:
/* NetTools.cpp
blade 7/12/2014 */
#include "NetTools.h"
using namespace std;
using namespace NetTools; // now this should work
int main()
{
cout << "testing" << endl;
return 0;
}
Sidenote:
You should really put everything inside the include guard:
/* Commands.h
blade 7/12/2014 */
#include "NetTools.h" // this should really go after the include guards
#ifndef COMMANDS_H
#define COMMANDS_H
namespace NetTools
{
}
#endif
There is no need to #include "NetTools.h" twice (even if it is include protected).
/* Commands.h
blade 7/12/2014 */
#ifndef COMMANDS_H
#define COMMANDS_H
#include "NetTools.h" // like this
namespace NetTools
{
}
#endif

Related

Undefined Reference when compiling C++

My code is similar to this one, but the problem is exactly the same: I'm getting an "undefined reference to `Test1::v" in Test1.cpp and in Test2.cpp when compilling the program in VSCode. What am I doing wrong? I'm a bit new on c++ so I just downloaded an extension that made me a project in c++ automatically. When I run the program using Ctrl + Shift + B it gives me this error, but when I do it with the Code Runner extension it doesn't detect the .cpp files.
// Test1.h
#include <iostream>
#include <vector>
using namespace std;
#ifndef TEST1_H
#define TEST1_H
class Test1{
public:
Test1();
static vector<Test1> v;
int a;
};
#endif
//Test1.cpp
#include "Test1.h"
Test1::Test1(){
a = 2;
v.push_back(*this);
}
//Test2.h
#include <iostream>
#include <vector>
using namespace std;
#ifndef TEST2_H
#define TEST2_H
class Test2{
public:
Test2();
double var;
};
#endif
//Test2.cpp
#include "Test2.h"
#include "Test1.h"
Test2::Test2(){
var = 5;
Test1::v[0].a += var;
}
//main.cpp
#include <iostream>
#include "Test1.h"
#include "Test2.h"
using namespace std;
int main(int argc, char *argv[])
{
cout << "Hello world!" << endl;
}
You have declared the static vector in the header file, but you need to define it in a cpp file. Add:
vector<Test1> Test1::v;
to your test1.cpp file. You can learn more about definition vs declaration here.
Also make sure you read this: Why is "using namespace std;" considered bad practice?
You could prepend the class name to call the variable directly since it's static. So, you could do something like:
Test1::Test1(){
// v.push__back(*this); // previous
Test1::v.push_back(*this); // now
}
in Test1.cpp. You'll then get a reference tooltip on your VS Code:
static std::vector<Test1> Test1::v
Which proves it's done.

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.

Multiple Class Files C++

I am unsure about the use of separate files for classes. How do I make functions inside the classes? Where do I put it?
QuizMain.cpp:
#include "QuizMain.h"
#include <iostream>
#include <string>
using namespace std;
QuizMain::QuizMain()
{
// Hia stackoverflow
}
QuizMain.h file:
#ifndef QUIZMAIN_H
#define QUIZMAIN_H
#include <string>
using namespace std;
class QuizMain
{
public:
QuizMain();
private:
};
#endif // QUIZMAIN_H
Main file:
#include <iostream>
#include <string>
#include "QuizMain.h"
using namespace std;
int main()
{
QuizMain qm;
return 0;
}
How would I make a class and call it correctly?
This is an example:
QuizMain.cpp file:
#include "QuizMain.h"
#include <iostream>
#include <string>
using namespace std;
QuizMain::QuizMain()
{
// Hia stackoverflow
}
void QuizMain::my_new_function(std::string my_name){
std::cout << "Hi " + my_name +"!" << std::endl;
}
QuizMain.h file:
#ifndef QUIZMAIN_H
#define QUIZMAIN_H
#include <string>
class QuizMain
{
public:
QuizMain();
void my_new_function(std::string my_name);
private:
};
#endif // QUIZMAIN_H
Main file:
#include <iostream>
#include <string>
#include "QuizMain.h"
using namespace std;
int main()
{
QuizMain qm;
qm.my_new_function("foo");
return 0;
}
Anyway, there is no point from asking such a question here. You should probably find a good book/resource and learn how to write and use functions.
Normally you have a header file and cpp file. The header file is where you declare your functions and member variables. The cpp file is where you implement your functions.
quizmain.h
// QuizMain.h file
#ifndef QUIZMAIN_H
#define QUIZMAIN_H
#include <string>
class QuizMain
{
public:
QuizMain(int quizScore);
// declare public functions here
private:
int quizScore; // declare private member variables here.
};
#endif // QUIZMAIN_H
cpp file
// QuizMain.cpp file
#include "QuizMain.h"
#include <iostream>
#include <string>
using namespace std;
QuizMain::QuizMain(int quizScore)
{
this.quizScore = quizScore; // init a quiz score
}
main
Call and create a class object like this
QuizMain quiz(95);
It is easy to do.
If you use the IDE project, the IDE set you to use the any file. Like code::block IDE But if you do not use the IDE project it is a little different to use.
You should write the .h file and then,after all writing you should put .cpp file.
Also you can use interface class that works by poiter.
/// .h file and declaration
#ifndef ONE.H
#define ONE.H
class one {
public:
one();
~one();
};
#include "one.cpp"
#endif ONE.H
then:
/// .cpp file and implementation
one::one(){
std::cout<<"constructor one"<<std::endl;
}
one::~one(){
std::cout<<"destructor one"<<std::endl;
}
then :
#include <iostream>
#include "one.h"
int main()
{
one o;
}
output:
constructor one
destructor one
Process returned 0 (0x0) execution time : 0.010 s
Press ENTER to continue.

How do I declare a namespace alias in a header file, then use it in a source file?

I want to put a namespace alias (ie namespace A = B::C) in a header file so I can use it in source files, but the compiler just tells me that its "not a namespace name". Any thoughts?
This is a very simplified axample of what I'm trying to do...
header file:
namespace A{
namespace B{
int getInt();
}
}
namespace AB = A::B;
source file:
#include "header_file.h"
#include <iostream>
int AB::getInt(){ // Error "AB is not a namespace name"
return 123;
}
You need to include the file that declares the namespace in the header file or as the comments say do this:
namespace B { namespace C { } }
namespace A = B::C;
At the point where you create the alias, the compiler must have already seen the aliased namespace.
Therefore, you must #include a file that contains said namespace or you must do this:
// "Forward Declaring" the namespace
namespace B { namespace C { } }
namespace A = B::C;

Restricting `using` directives to the current file

Sorry for this silly question, but is there any way to restrict using directives to the current file so that they don't propagate to the files that #include this file?
No, there isn't, which is why you should not use using directives in header files, or any other file that you #include.
Perhaps wrapping the code to be included inside its own namespace could achieve the behavior
you want, since name spaces have scope affect.
// FILENAME is the file to be included
namespace FILENAME_NS {
using namespace std;
namespace INNER_NS {
[wrapped code]
}
}
using namespace FILENAME_NS::INNER_NS;
and in some other file
#include <FILENAME>
// std namespace is not visible, only INNER_NS definitions and declarations
...
Technically you should be able to import them to some internal namespace, and then make the things declared in that visible in the namespace meant for the user.
#ifndef HEADER_HPP
#define HEADER_HPP
#include <string>
namespace my_detail
{
using std::string;
inline string concatenate(const string& a, const string& b) { return a + b; }
}
namespace my_namespace
{
using my_detail::concatenate;
}
#endif
#include <iostream>
#include "header.hpp"
using namespace my_namespace;
int main()
{
std:: //required
string a("Hello "), b("world!");
std::cout << concatenate(a, b) << '\n';
}
Not sure if it is worth the trouble and how well it plays with "argument-dependent lookup".