I am trying to stop a class from being able to convert its \'this\' pointer into a pointer of one of its interfaces. I do this by using private inheritance via a middle prox
You should be able to access Base::Enum
by fully qualifying it:
class Child : public Middle
{
public:
void Method()
{
::Base::Enum e = ::Base::value;
}
};
This is the behavior specified by the language (C++03 §11.2/3):
Note: A member of a private base class might be inaccessible as an inherited member name, but accessible directly.
This is followed by an extended example that is effectively similar to your example code.
However, it appears that neither Visual C++ 2008 nor Visual C++ 2010 correctly implements this, so while you can use the type ::Base::Enum
, you still can't access ::Base::value
. (Actually, Visual C++ seems to have gotten a lot of this wrong, as it incorrectly allows you to use the not-fully-qualified Base::Enum
).
To "get around" the problem, you can add using declarations to the Middle
class:
class Middle : private Base
{
protected:
using Base::Enum;
using Base::value;
};
This won't let you use Base::Enum
or Base::value
in your Child
class, but it will allow you to use an Enum
and value
or Middle::Enum
and Middle::value
.
I only have one question: why you private inheritance at all ?
Inheritance is quite a broken concept, in my opinion, because it violates the One Responsibility principle:
Unfortunately inheritance is required for polymorphism in Object-Oriented code, so you can't shy away from it in this case.
But here you explicitly wish NOT to use polymorphism, so I find myself wondering why using inheritance at all, since it's its sole interesting use (imo).
Instead, in C++, you can use:
using
, typedef
etc... to bring objects from outside the classYour example seems constrained here, but I too wrap my enums into struct
to prevent namespace pollution by a thousand symbols (and because struct
can be used as template parameters wheres namespaces cannot).
struct MyEnum
{
enum type
{
value
};
};
class Child
{
public:
typedef MyEnum::type Enum;
Child(Enum e = MyEnum::value);
private:
};
I don't see anything wrong with qualifying the name, instead I feel it makes it easier to read again, since you know which enum we are talking about...
Really, private
inheritance is best avoided (and usually replaced by Composition). The only valid case (imo) is for Empty Base Optimization... and frankly it's not often you need it (as usual with optimizations).