views:

117

answers:

2

How to implement casting to a private base class in C++? I don't want to use hacks such as adding a friend etc. Defining public casting operator does not work.

EDIT :

For example I have:

class A {
//base class
}

class AX : private A {
//a child
}

class AY : private A {
//another specialized child
}

class B {
//base class
void do (A a) {//do
    }
}

class BX : private B {
//a child
void do (AX a) {
     B::do( static_cast <A> (a) );
    }
}

class BY : private B {
//another specialized child
void do (AY a) {
    B::do( static_cast <A> (a) );
    }
}

EDIT2

Why do I do this?

Suppose I have to define some property which is quite heavyweight and can be of several similar types (like VelocityX VelocityY etc). Then I want to be able to have classes which can have any set of these properties. If I want to process these properties, it is obvious, that I'd rather cast them to their base type than to add an implementation for each variation. I do not use public inheritance because it's better to explicitly cast where needed than to have the private interface implicitly visible. Not a real problem but I'd like to have a solution :)

+3  A: 

You can just use a C-style cast. No need for any "hacks" or "implementations". Wrapping it into an explicit function serves the "C-Style casts are bad" people

template<typename Targ, typename Src>
typename boost::enable_if<boost::is_base_of<Targ, Src>, Targ>::type &
private_cast(Src &src) { return (Targ&)src; }

To have the cast safe, you need to ensure that Targ is actually a private or public base. This is done by boost::is_base_of.


Of course you should prefer member functions in the respective derived class that return the base pointer, instead of doing such a cast..


Defining public casting operator does not work.

That doesn't make sense to me... Why make the base class private at all then? Just make it public. The reason your conversion functions don't work is because the Standard requires that implicit conversions never consider conversion functions to a base class, the class itself or void.

Johannes Schaub - litb
The result of your C-style cast (equivalent to reinterpret_cast in this case) is implementation-defined, isn't it?
avakar
@avakar it is not equivalent to a reinterpret_cast, but to a static_cast with access checking disabled (see `5.4/7`).
Johannes Schaub - litb
My deity, it's true! +1 from me.
avakar
+4  A: 

If defining a public casting operator does not work, you can try with a regular function:

class D: private B {
    public:
        B& asB() { return static_cast<B&>(*this); }
};
...
D d;
d.asB().methodInB();
...

Anyway, what is the point? If D derives privately from B, then you are not supposed to use a D as a B from the outside.

gpeche
+1 - This would have been my comment to, including the "What's the point?" question.
T.E.D.