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 proxy class. The problem is that I find private inheritance makes all public static members and types of the base class inaccessible to all classes under the inheriting class in the hierarchy.
class Base
{
public:
enum Enum
{
value
};
};
class Middle : private Base
{
};
class Child : public Middle
{
public:
void Method()
{
Base::Enum e = Base::value; // doesn't compile BAD!
Base* base = this; // doesn't compile GOOD!
}
};
I've tried this in both VS2008 (the required version) and VS2010, neither work.
Can anyone think of a workaround? Or a different approach to stopping the conversion?
Also I am curios of the behavior, is it just a side effect of the compiler implementation, or is it by design? If by design, then why? I always thought of private inheritance to mean that nobody knows Middle inherits from Base. However, the exhibited behavior implies private inheritance means a lot more than that, in-fact Child has less access to Base than any namespace not in the class hierarchy!
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With