way to separate non-class library into header and implementation - c++

Let's say there is a library named test, the header "test.hpp" is like follows:
namespace test
{
int myfun(int a);
}
And as for the implementaion, which style is better?
#include"test.hpp"
int test::myfun(int a){
return a*a;
}
or
#include"test.hpp"
namespace test
{
int myfun(int a){
return a*a;
}
}

Suppose you have multiple namespaces or nested namespaces in your header as :
namespace test{
namespace subtest{
int Foo(int);
//many other functions go here
} //namespace subtest
} //namespace test
And
namespace test1{
int Foo(int);
}
namespace test2{
int Bar(int);
}
In these cases you should always go with Second implementation as it makes your code more readable and easy to debug.
First one :
#include "test.hpp"
int test::subtest::Foo(int x){return x;}
//many other goes here
Look as the nesting increase everytime to define a function, you need to write fully specified name of the function (repeating namespaces again again).
Second one :
#include "test.h"
namespace test{
namespace subtest{
int Foo(int x){return x;}
//other go here
}
}
This solves namespace name repetition also you can easily refactor things. To debug or refactor a namespace's content simply jump to it's first declaration and change the things. You can also collapse the code under single namespace. (With most ide) making you code more beautiful.
Similarly for multiple namespaces
First one :
#include "test.hpp"
int test1::Foo(int x){return x;}
int test2::Bar(int x){return x;}
How difficult it gets to debug things. Moreover if under two namespace same function name occurs you will have good time debugging.
Second one :
#include "test.hpp"
namespace test1{
int Foo(int x){return x;}
}
namespace test2{
int Bar(int x){return x;}
}
All the declaration within a namespace will be together. So debugging and jumping within namespace will be ease.
Also most open source projects use second implementation

Related

C++ question about `using namespace ns` and explicit namespace `ns::my_method()`

I declare a namespace in file test.h as follows:
namespace dev {
class test {
public:
test();
~test();
int m_number;
};
int sumInt(int, int);
}
When I complete file test.cpp as follows:
using namespace dev;
test::test() {
m_number = 1;
}
test::~test() {}
int sumInt(int a, int b) {
return a + b;
}
There occurs an error "Unresolved external symbol dev::sumInt(int,int)"
So I have to explicit introduce function sumInt to namespace dev like:
int dev::sumInt(int a, int b);
I'm very confused that when I using the namespace dev in file test.cpp,
why should method sumInt() be explicit defined in namespace dev,but class test should't be?
Sorry my English is poor,I have try my best to describe the question clearly.
I hope someone can enlighten me.

Separating interface from implementation isn't working c++

Hey i was trying to use Separating interface from implementation but got error.
Not understanding what's wrong.
Here's my program
here's the error image
#include<iostream>
#include"name.h"
using namespace std;
int main()
{
int x,y;
cin>>x>>y;
name n1(x,y);
n1.getdata(x,y);
n1.showdata();
}
now here's the created header file
#include<iostream>
using namespace std;
class name{
private:
int a,b;
public:
name(int x, int y);
void getdata(int x, int y);
int showdata();
};
& here's the next part of class
#include"name.h"
using namespace std;
name::name(int x, int y)
{
a=0;
b=0;
}
void name::getdata(int x,int y)
{
a=x;
b=y;
}
void name::showdata()
{
cout<<a+b;
}
There are many problems with your code. It looks like the best advice in this situation would be to read a good C++ book.
When this is out of the way, here's the short-list of problems in the severity-descending order:
name::showdata() declaration signature does not match difinitioin: int showdata() vs. void showdata()
header misses an include guard
using namespace in a header is a code smell 99 times out of 100
header does not need to include <iostream>, it would suffice to include it in implementation file, where it's actually used.
By looking at undefined references you are getting, I would also guess that name.cpp is not build.
I fixed some of the mentioned points to just make it build:
Live Demo

How does C++ know where to look for the namespace specified using "using namespace ..."?

For eg., when using OpenCV, we specify
using namespace cv;
But where does C++ look down to know where it is defined?
using namespace will not make everything declared in that namespace visible. It will expose only what translation unit "sees".
Consider following code
One.h
#pragma once
namespace ns
{
void function1();
}
Two.h
#pramga once
namespace ns
{
void function2();
}
main.cpp
#include "Two.h" // <-- included only Two.h
using namespace ns;
int main()
{
function2(); // <-- is a ns::function2() located in Two.h
function1(); // <-- error compiler does not know where to search for the function
return 0;
}
What happened here is the compiler created translation unit with all preprocessor directives resolved. It will look something like this:
namespace ns
{
void function2();
}
using namespace ns;
int main()
{
function2(); // <-- OK. Declaration is visible
function1(); // <-- Error. No declaration
return 0;
}
How does C++ know where to look for the namespace specified using using namespace …?
It doesn't.
When you use
using namespace cv;
the scope of search for names (of classes, functions, variables, enums, etc) is expanded. The names are searched in the cv namespace in addition to other scopes in which they are normally searched.

Avoid re-definition in C++

I would like to avoid re-definition from two different include files as follows:
File ABC.h
extern int v=1;
File foo.h
#include "ABC.h"
class Foo
#ifdef BLA
: public ABC
#endif
{
...
};
File bar.h
extern int v=3;
Main:
#define BLA
#include <foo.h>
#include <bar.h>
Basically foo is a class written by me, and bar is a third-party library. But it doesn't seem to work. How should I solve the problem?
Sorry, it's a bit hard to describe, the example is kind of bad as the conflicted parts are actually not variables, but something like #define and wrapped in big blocks of code (error message is: "multiple definition of `__vector_17'"). Is there a way to solve it without using a namespace?
Using a namespace you can solve this problem:
namespace foo
{
int val =1;
}
namespace bar
{
int val =3;
}
using namespace foo;
int x = val; //Now x will be assigned with 1
A namespace is what you need:
namespace foo
{
int v =100;
}
namespace bar
{
int v =500;
}

operator declaration within namespace in a header?

Please excuse me but I didn't know to give a name to the title in a short way.
Why do I need to declare an overloaded operator inside the header to make it work in this example:
HEAD.H
#pragma once
namespace test {
class A {
public:
A() : x(0) {}
int x;
};
A& operator++(A& obj); //this is my question
}
HEAD.CPP
#include "head.h"
namespace test {
A& operator++(A& obj) {
++obj.x;
return obj;
}
}
MAIN.CPP
#include <iostream>
#include "head.h"
using namespace std;
using namespace test;
int main() {
A object;
++object; //this won't work if we delete declaration in a header
return 0;
}
operator++ is defined and declared in a namespace inside "head.cpp" so why do I need to declare it one more time in a header?
Thank you.
The CPP files are compiled independently of each other, and they only see the header files they've included (which are in fact textually added to the source code of the CPP before compilation). As such you'll use the header file to inform the compiler that a function exists with that signature (be it an operator overload).
Then the output from your CPP files is put together by the linker, which is when you'd find out if for instance you had declared a function in a header file but never taken the trouble to implement it.
Simple example with namespaces:
#include <iostream>
namespace test{
int f() { return 42; }
int g() { return -1; }
}
namespace other{
int f() { return 1024; }
}
using namespace other;
int main(){
//error: 'g' was not declared in this scope
//std::cout << g() << std::endl;
std::cout << test::f() << std::endl; //42
std::cout << f() << std::endl; //1024
return 0;
}