I have a few classes in my project that I would like to wrap into a namespace. I am using inheritance to make some child classes inherit properties from the parent.
I am wondering what the correct way is to define a namespace for the child classes. I tried declaring my parent class as:
namespace myNamespace {
class A {
...
};
}
And then in the child class:
class B : public A {
...
};
However this does not seem to put class B in the same namespace as A (myNamespace ).
There is not smart trick to do that. Namespaces are completely unrelated to classes or inheritance concept.
You should declare B in namespace as usual:
namespace myNamespace {
class B : public A {
...
};
}
Or put B definiton in the same block as A (if they are defined in the same file)
namespace myNamespace {
class A {
...
};
class B : public A {
...
};
}
You cannot inherith namespace. There is not such a feature in C++.
What you can and should do is simply wrap your child class definition in the same namespace of your parent class as in the following:
namespace myNamespace { //same namespace of A
class B : public A {
};
}
Related
I have some shared files that I want to use between two programs A and B that have the same compile target and are very identical.
So, I tried to separate them into two namespaces and create a shared namespace for the shared files
Interfaces.h
namespace ns_s {
class SomeClass;
class IFoo {
virtual void bar(SomeClass*) = 0;
};
}
SomeHeaderinA.h
#include "Interfaces.h"
namespace ns_a {
using namespace ns_s;
class Foo : public IFoo {
virtual void bar(SomeClass* p) override { ... }
};
}
However the compiler is complaining now that my member function bar does not override anything, so it seems to not see the interface implementation.
Why is that the case? And why does the compiler not already complain about a missing class IFoo?
EDIT:
Looks like I missed an essential part that contributes to the problem. I pre-declared a class that is a parameter of the interface method. Now that I ahve a pre-declaration in namespace shared and an actual declaration in namsepace A those things are not the same anymore.
Is there a good way to fix this? Only a small subset of interfaces have arguments that are defined in one or the other namesapce (A or B), so I could leave different implementations in each of them, but it would be nice to have it all in the shared space if possible in a clean fashion.
Here is a link
http://coliru.stacked-crooked.com/a/79fa58e50e7b8637
Problem
As shown in the linked code, the problem is caused by SomeClass.
The line
class SomeClass{};
declares and defines SomeClass in namespace ns_a. It does not define SomeClass in namespace ns_s.
The declaration of class ns_s::IFoo::bar uses ns_s::SomeClass.
The declaration of class ns_a::IFoo::bar uses ns_a::SomeClass.
That's the override is an error.
Solution
You can fix it by:
Removing the definition of SomeClass from ns_a, or
Using ns_s::SomeClass in the declaration of ns_a::IFoo::bar.
namespace ns_a {
using namespace ns_s;
class Foo : public IFoo {
virtual void bar(SomeClass* p) override {}
};
}
or
namespace ns_a {
using namespace ns_s;
class SomeClass{};
class Foo : public IFoo {
virtual void bar(ns_s::SomeClass* p) override {}
};
}
I am porting code from Java to c++ and I'd like to replicate some anonymous functionalities.
In file A.h I have :
class A
{
private:
int a;
class AnonClass;
friend class AnonClass;
};
In file A.cpp I have :
namespace
{
class AnonClass
{
public:
AnonClass(A* parent)
{
parent->a = 0; // This doesn't work, a is not accessible
}
}
}
Is it possible to friend a class in an anonymous namespace in C++?
In Java you can declare anonymous classes so it would be very similar. Also it would not expose AnonClass to clients of A.h
Less known alternative is to make class Anon a member class of A. Inside class A you only need a line class Anon; -- no real code, no friend declaration. Note it goes within class A, almost as in Java. In the .cpp file you write all the details about Anon but you put it not in anonymous namespace but withinA::
class A::Anon { ..... };
You can split declaration and implementation of A::Anon, as usual, just remeber always add A:: to Anon.
The class Anon is a member of A and as such gets access to all other members of A. Yet it remains unknown to clients of A and does not clutter global namespace.
As far as I can see you can not. The reasons:
The “anonymous” namespace is accessible only within the file you created it in.
You have to define whole AnonClass class and it's functions in one namespace, i.e. in one place in the program.
Class A has to be defined before AnonClass constructor.
AnonClass has to be at least declared before class A.
So you see, you can't break AnonClass definition on two parts. And you can't define it both before and after A class.
The only option - put class A into the same anonymous namespace. This code works:
namespace
{
class A
{
public:
A():a(0){};
private:
int a;
friend class AnonClass;
};
class AnonClass
{
public:
AnonClass(A* parent);
};
AnonClass::AnonClass(A* parent)
{
parent->a = 0;
};
}
int main() {
A a;
return 0;
}
I hope this helps.
I currently have the following two classes
class TOrder
{
public:
private:
.......
};
Now my other class is :
#include "TOrder.h"
namespace namespaceA
{
namespace namespaceB
{
class OrderDis
{
private:
TOrder* frmPointer;
.....
};
}
}
The above works fine the problem starts when I use an object of OrderDis in TOrder as such
#include <QMainWindow>
#include "OrderDis" //Added - Creates Problem
class TimedOrder
{
public:
.......
};
Any suggestion on how I could use forward declaration to resolve my issue ?
You could forward OrderDispatcher in TimeOrder.h
namespaceA
{
namespaceB
{
class OrderDispatcher;
}
}
class TimedOrder
{
//...
};
The forward declaration can be written as:
namespace A{ namespace B{ class OrderDispatcher; } }
As you only use a pointer to TimedOrder in the OrderDispatcher class, it can be solved by simply not including TimedOrder.h in the OrderDispatch.h file. Instead just declare the TimedOrder class:
class TimedOrder;
No need to muck about with namespaces and such then.
Note: You can't declare it in any of the namespaces, declare it instead where you now do your #include.
I have the following situation:
namespace MyFramework {
class A {
void some_function_I_want_B_to_use() {}
};
class B {
B() {
some_function_I_want_B_to_use() {}
}
};
}
where I want the some_function_I_want_B_to_use to not be visible outside of the MyFramework namespace, but I do want it to be visible to anyone inside of MyFramework (alternatively, visible to just class B is also ok). I've got a number of methods like this, is the only way to hide them from the public API of MyFramework to make all classes within MyFramework friends? I was also considering placing all "lower-level" classes inside of B, but I don't want to go down that route until I'm sure it would accomplish the ability to access all of A's methods from inside of B but not from outside of MyFramework.
To restate, I've got a framework that's all created within one namespace, and each class has methods that are useful to the general public using the framework. However, each class also has a few methods that complicate the public API but are needed for the framework to function properly.
I want the some_function_I_want_B_to_use to not be visible outside of the MyFramework namespace, but I do want it to be visible to anyone inside of MyFramework.
In summary, you want something similar to packages in Java.
Unfornately for you, that is not possible with namespaces. Every class included in a namespace is accessible from the outer of the namespace: namespaces are open.
The solution is usually to add another namespace for implementation details:
namespace MyFramework
{
// Implementation details
// Should not be used by the user
namespace detail
{
class A
{
public:
void func();
};
}
class B
{
public:
B()
{
A a;
a.func();
}
};
}
Don't forget to add a comment stating the detail namespace is not to be used by user.
Pimpl idiom, frequently called Compilation Firewall, is what you are looking for. The whole Qt is implemented using this idiom.
// A.hpp
namespace MyFramework {
class A {
private:
class Private;
Private* implementation;
};
}
// A_Private.hpp
#include "A.hpp"
namespace MyFramework {
class A::Private {
public:
void some_function_I_want_B_to_use() {}
};
}
// A.cpp
#include "A_Private.hpp"
namespace MyFramework {
A::A() {
implementation->some_function_I_want_B_to_use();
}
}
// B.hpp
#include "A.hpp"
namespace MyFramework {
class B {
B();
A a;
};
}
// B.cpp
#include "A_Private.hpp"
namespace MyFramework {
B::B() {
a.implementation->some_function_I_want_B_to_use();
}
}
NOTE: Of course A_Private.hpp does not go into the include directory of you framework final distribution, i.e. it remains package private as you require.
The example is very basic. Of course it can be made more advanced and robust. Additionally, Pimpl has lots of other advantages. For all this information refer to:
GotW #100: Compilation Firewalls (Difficulty: 6/10)
GotW #101: Compilation Firewalls, Part 2 (Difficulty: 8/10)
Pimp My Pimpl — Reloaded
Pimp My Pimpl
Dpointer
The common convention, e.g. in Boost, is a nested namespace called detail.
If you want to enforce the accessibility you can always instead use a nested class called detail. The class provides accessibility checking, but lacks extensibility like a namespace. However, a detail scope will rarely if ever need extension.
So, in all its ugliness,
namespace my_framework {
class detail
{
private:
static void some_function_I_want_B_to_use() {}
public:
class A
{};
class B
{
B() { some_function_I_want_B_to_use(); }
};
};
typedef detail::A A; // "using detail::A"
typedef detail::B B; // "using detail::B"
} // namespace my_framework
In passing, note that class B (straight from the question) has a private default constructor so no instances of it can be created.
I've got a scenario like the following:
class criterion
{
// stuff about criteria...
};
namespace hex {
class criterion : public criterion //does not compile
{ //This should inherit from the
//A hex specific criterion //criterion class in the global namespace
};
};
My question is -- how does one inherit from a class in a namspace which is the parent of another namespace?
Billy3
You need to specify the namespace, in this case the global one:
class criterion : public ::criterion
Note that c++ doesn't specify any means of navigating namespaces as if they were a tree. For example, you can't specify the the "parent" namespace using ".." or any other shorthand - you have to use its name.
Start with "::"
For example
class criterion : public ::criterion {};
Simplified basic C++ namespace rules are:
You can access anything in parent namespace path without specifying namespace.
You can access anything in child namespace path by specifying only relative path.
Everything else requires full namespace specifications.
This compiles for me, basically just explicitly show in what namespace the parent class is:
class A
{};
namespace B {
class A : public ::A
{};
namespace C {
class A : public B::A
{};
}
};