Sorry if this is a dumb question, but I am learning C++ (I usually code in C) and I don't understand how to use namespaces and classes. Do they have to be declared in header files? How do I declare functions in a namespace? And let's say I am working on a large project with different files. And I define a namespace in a file, but then want to add more functions to that same namespace, but those functions are defined in another file. Can that be done? For example:
file1.cpp
namespace Example {
int vartest;
void foo();
}
file2.cpp
int othervar;
void otherfoo(); // How can I add this and othervar to the Example namespace?
Thanks!
Simply declare it an equivalent1 namespace of the same "name" !
file1.cpp
namespace Example {
int vartest;
void foo();
}
file2.cpp
namespace Example {
int othervar;
void otherfoo();
}
Namespaces are merged.
Do they have to be declared in header files?
No. You can declare any namespace inside a namespace. (Note that the "global scope" is also a namespace)
How do I declare functions in a namespace?
Simply declare it within the namespace. As you have done.
And let's say I am working on a large project with different files.
And I define a namespace in a file, but then want to add more
functions to that same namespace, but those functions are defined in
another file. Can that be done?
Namespaces of the same name, within the same namespace are merged.
namespace X { void foo(){} }
namespace X { void foo(){} } //Error, redefinition of `foo` because the namespace ::X is merged
namespace X { void foo(){} }
namespace Y { void foo(){} } //Ok. Different name spaces...
namespace X { void foo(){} } // ::X
namespace Y { void foo(){} } // ::Y
namespace Y {
namespace X { // namespace ::Y::X here isn't same as ::X
void foo(){} //OK
}
}
1 recall that the so called "global scope" is actually a namespace known as global namespace
Related
I'm doing online programming tests like leetcode, which requires only one .cpp file, so I have to place everything into one .cpp file.
And I used to write main() function ahead of any other functions, but that way I have to forward declare every function I use, which is very annoying. So I think of something like the snippet below:
namespace function;//oop,there is no such forward declaration
int main()
{
using namespace function;//compiler could not find this actually;
f1();
...
}
namespace function
{
f1(){...};
f2(){...};
...
}
But the compiler complains, since there is no forward declaration of namespaces (unlike functions), which makes the namespace invisible to the compiler.
Is there any way to forward declare a namespace? Just like
void f1();
int main()
{
f1();//ok,because there is a forward declaration
}
void f1()
{ ...}
The nearest thing to forward-declaring a namespace is to rely on the fact that they can be split up (unlike a class declaration), even into different translation units! Hence you can write
namespace funcion // [sic]
{
}
before main. Note well the braces.
If not having to forward declare functions is the most important goal, you can abuse the fact that a class also defines a namespace scope where you don't have to forward declare member functions.
Something like this:
struct program
{
int main()
{
f1();
f2();
return 0;
}
void f1(){}
void f2(){}
};
// The real main still needed here
int main()
{ return program{}.main(); }
Technically this works, but still not really recommended.
This won't solve your problem.
You can declare the namespace earlier like this:
namespace function {};
int main()
{
using namespace function;
f1();
}
namespace function
{
void f1() {}
}
but f1 is still not declared in main.
How about extracting the function declarations to a header file and including it?
somefile.h
#pragma once
namespace function {
void f1();
};
somefile.cpp
#include "somefile.h"
int main()
{
using namespace function;//compiler could not find this actually;
f1();
}
namespace function
{
void f1() {}
}
so I have to place everything into one .cpp file
Then just forget the #include and do one of the following:
a. put the declaration namespace function { void f1(); } above int main() and the definition (function body) below int main()
b. put the int main() last, so that you don't require additional declarations
How can I create bunch of methods that doesn't depend on any object ( in my file there is no classes , no objects , no main , nothing but the methods) all in one cpp/hpp file and how to declare them ?
Create a namespace. Something like this:
Utils.h
namespace Utils
{
void myMethod();
}
Utils.cpp
namespace Utils
{
void myMethod()
{
//Implementation
}
}
If you want them to be public, i.e. available in multiple translation units, the best way is to include them in a namespace, declare them in the header and implement them in a single implementation file:
//functions.h
namespace MyFunctions
{
void foo();
void goo();
}
//functions.cpp
namespace MyFunctions
{
void foo() {}
void goo() {}
}
IMPORTANT
If you provide the definition in the header, you should mark them inline, otherwise including that header in multiple translation units might result in a linker error:
//functions.h
inline void foo() {
//..
}
inline void goo() {
//..
}
If you only want them available in a translation unit, define them in that implementation file in an anonymous namespace (or declare them static):
//fileThatUsesFunctions.cpp
namespace
{
void foo() {}
void goo() {}
}
You declare them the same way you would in C. It can be within a namespace or outside of a namespace. There is no difference other than the fact that they are not in a class.
If you want to use the functions in C later you should prepend them with extern "C".
extern "C" void foo();
Nothing stops you from writing free functions. If you think that a function should be global then free functions are quite appropriate.
You should place them in a namespace. Naveen's example is spot on.
As an additional note, if you wish to hide certain functions or data units within the namespace (thereby mimicking 'private' access), place those functions and data units in an anonymous namespace, nested within the parent namespace. For example:
namespace Foo
{
publicFunction1();
publicFunction2();
namespace
{
privateFunction1();
std::vector<Bar> privateData;
}
}
Items within a nested, anonymous namespace are only accessible to the items within the parent namespace. I've found this to be singularly useful.
To define a function that doesn't depend on an object simply declare them directly.
// MyFile.h
int some_function();
// MyFile.cpp
int some_function() {
return 42;
}
Using C++ though it would be a good idea to declare them in a namespace though. This doesn't give them a dependcy on an object but does reduce global namespace pollution
// MyFile.h
namespace MyNamespace {
int some_function();
}
// MyFile.cpp
using MyNamespace;
int some_function() {
return 42;
}
I have declared a class X in X.h as follows:
namespace Foo {
class X{
....
};
}
In X.cc I would like to define the constructors, methods for X.
Do I need to enclose all my definitions inside namespace Foo {...}
or prefix X as Foo::X:: for every method ?
It seems that sometimes I can just say (using namespace Foo) and not mention it again,
i.e. just define methods as
X::X() {...}
What is the correct approach here ?
Any of the three approaches you suggest will work. Given:
namespace N {
struct S {
int F();
};
}
You can put the definition in a namespace block:
namespace N {
int S::f() { return 42; }
}
You can qualify the member name with the namespace name:
int N::S::f() { return 42; }
Or you can use a using directive (I'd not recommend this, though):
using namespace N;
int S::f() { return 42; }
Generally, I'd recommend against using a using directive. As for the other two (using a namespace block or qualifying the names), I don't think it really matters. I do both in my code.
No, you don't need to use namespace Foo {...} while defining your class. All your approaches are valid, but personally I'd prefer the following:
// In FOO.h
namespace FOO
{
class A
{
public:
A();
};
}
And the implementation:
// In FOO.cpp
#include "Foo.h"
FOO::A::A()
{
cout<<endl;
}
I want to use an 3rd party library without using its header file. My code resides in its own namespace, therefore I can't use conventional forward declaration as I don't want to pollute the global namespace. Currently I have something like that:
3rd-party-library.h----
typedef struct {...} LibData;
void lib_func (LibData *);
my-source.h-----
namespace foo {
/*forward declaration of LibData*/
class Abcd {
public:
void ghj();
private:
Libdata *data_;
};
}//namespace foo
my-source.cpp-----
#include "my-source.h"
#include <3rd-party-library.h>
namespace foo {
typedef ::LibData LibData;
void Abcd::ghj() {
//do smth with data_
}
}//namespace foo
Is it possible to forward declare a global type in a way that it would reside in an namespace? Plain simple typedef does not work.
For a forward declaration to work, you need to forward declare an object in the proper namespace. Since the original object resides in the global namespace, you need to forward declare it in the global namespace.
If you don't like that, you can always wrap the thing in your own structure:
namespace foo {
struct libDataWrapper; }
and in your own cpp define this structure. Or you can always resort to void* and the like, if you're up to that sort of thing.
since you are using pointer, i''' just forward declare a dummy object inside your own namespace, then use reinterpret_cast to bind the actual object to existing pointer.
your-source.h
namespace foo {
//forward declare
class externalObj;
class yourObj
{
public:
yourObj();
~yourObj();
void yourFunction();
private:
externalObj* pExt;
};
}
your-implementation.cpp
#include "your-source.h"
#include "externalObj-header.h"
namespace foo {
yourObj::yourObj() :
pExt ( reinterpret_cast<externalObj*>(new ::externalObj()) )
{
}
yourObj::~yourObj()
{
}
void yourObj::yourFunction()
{
reinterpret_cast<::externalObj*>(pExt)->externalFunction();
}
}
Can't you just simply wrap the include for the third-party library in its own namespace?
namespace ThirdParty {
#include "thirdparty.h"
}
namespace foo {
... your code
ThirdParty::LibData *d;
}
I have some inline functions contained within a namespace in a header file and am not currently in a position to move them into a cpp file. Some of these inline functions use magic constants, for example:
// Foo.h
namespace Foo
{
const int BAR = 1234;
inline void someFunc()
{
// Do something with BAR
}
}
However, I want to make these magic constants private - any ideas how? My first thought was to use an anonymous namespace thus:
// Foo.h
namespace Foo
{
namespace
{
// 'private' constants here
const int BAR = 1234;
}
inline void someFunc()
{
// Do something with BAR
}
}
However, this doesn't work and Foo::BAR is available to any cpp file that includes Foo.h? Is there a way to do this without creating an implementation cpp file?
You can't, anonymous namespaces work for the translation unit they are defined in (or included into in your case).
You could consider moving them into a detail namespace to signal to the user that they are internal details:
namespace foo {
namespace detail {
int magic = 42;
}
// ... use detail::magic
}
How about:
namespace Foo {
class foo_detail {
private:
enum {
BAR = 1234,
};
friend void someFunc();
};
inline
void someFunc() {
// something with foo_detail::BAR
}
}
This makes the constant nonaccessible for anyone else than the functions you mark as friends. You can make the class nonconstructable by making the constructor private to make sure that noone does try to instanciate the class.
Put them in a special namespace or name them specially, combined with a project convention that such things are non-public:
namespace foo {
namespace detail { // as in "implementation details"
inline int answer() { return 42; }
const int perfect = 28;
}
std::string _question(); // not part of foo's "public interface" by convention
int this_is_public() {
using namespace detail; // now don't have to prefix detail::
return answer() + perfect + _question().length();
}
}
Anyone using names documented as non-public will circumvent any "protection" you try; which highlights the real concern: documenting what's part of the public interface and may be relied upon.
Unnamed namespaces solve a different problem: getting names unique to a particular TU. They won't help here.