Getting rid of error C2243 - c++

Is it possible to getting rid of error C2243?
class B {};
class D : protected B {};
D d;
B *p = &d; // conversion from 'D *' to 'B &' exists, but is inaccessible
I had this error in my app and at the end I've managed to compile it by making an explicit conversion:
D d;
B *p = (B*)&d;
I can't understand why by making class D inherited protected from B makes the implicit conversion inaccessible.
I tried to avoid explicit conversion by creating a operator B() in class D in order to make the conversion accessible:
class B {};
class D : protected B
{
public:
operator B() {return *this;}
};
But there is no way.
Any other solution to avoid explicit conversion?

If you want to allow conversion, you should be using public inheritance.
Using protected or private inheritance, you are declaring that the fact that the derived type inherits from the base class is a detail that should not be visible from the outside: that's why you are getting that error.
You should regard non-public inheritance only as a form of composition with the added possibility to override methods.

Because protected and private inheritance are not is-a relationship, they are just syntax sugar for composition. Your classes can be rewritten exactly like this, but you lose the convenience of letting the compiler define b for you, and using b members directly instead of referring to it explicitly :
class D
{
protected:
B b;
};
For the second point of your question:
operator B() {return *this;}
This line has to do with B and D. D* and B* are totally different from B and D though they are pointers to them! to cast pointers, you could reinterpret the pointer:
B *p = reinterpret_cast<B*>(&d); // TOTALLY WRONG, although it compiles :)
Don't do the above line! I think you might give us more info of what you are trying to achieve.

Because out of D and Ds children, nobody knows that they are parent-child, so you need to do it explicitly.
Thats what protected inheritance means, only your family(children) will know that you inherit. And you could use it, for example in a children method, there an implicit conversion would be legal.
If you want to have implicit conversion out of your children you need to make it public for everyone to know.

The problem here is that you are trying to do an end run around the information hiding that the protected attribute provides. If you want to access an instance of D as a B, why have you inherited it as protected rather than public?. What you are saying in using protected inheritance is that you wish only instances of D and its descendants to be aware of the B component. You need to look again at what you want to accomplish.
The old C style cast that you are using has none of the subtlety of the newer C++ casts so it gives you code that will compile but the problem is really in the inheritance.

Did you try making operator B() public in class D? In the code you showed, it would be marked protected and still inaccessible. But I would avoid conversion operators in general if possible.
Still, inheriting protected B means you intend to prevent doing B* p = &d. Imagine if B was actually a protected member variable at the top of D. Just like you can't access D.b in that case, you can't access d as a B*, unless you cast it away.
So either inherit B publically, or use your casts. I'd go with inheriting B publically, because inheriting it protected basically says "Don't use me as a B", which you are trying to do anyway.

Because nobody outside knows they are parent-child,you only can perform this action in D's derived class.This is an example(Test in Visual Studio 2013):
class BASE{};
class BASE1 :protected BASE{};
class BASE2 :protected BASE1
{
public:
void func(BASE &a, BASE1 &b){a = b;}
};
void main()
{
BASE a;
BASE1 b;
BASE2 c;
c.func(a, b);;
system("pause");
}

Related

What's the best solution to convert base class to a derived class?

Consider we have an library that contains a base class, like below,
class Base{
protected:
int a;
public:
Base(int a) : a(a) {}
};
Then, I want to extend it in a new library by adding a new function, like below
class Derived : public Base{
public:
bool is_greater(Derived &y) { return a > y.a; }
};
So that, we can compare their member values using member function is_greater, as
int main(){
Base b1, b2 = // get from the old library's output
Derived d1 = b1, d2 = b2 // convert from base class to derived class
d1.is_greater(d2);
}
So, what's the best solution for this kind of conversion?, performance is the most important point I am concerned about.
Just like any other conversion. You can use a converting constructor:
explicit Derived(const Base& base): Base(base) {}
Conversion operator isn't a practical option in this case since the base doesn't know about the derived type.
Extending a class to add functionality is only viable when either
The class is designed to be extended that way, polymorphic with appropriate APIs, or
You use your extended class everywhere, not the base class.
... otherwise, there is no way to avoid copies or dangerous casts with potential undefined behavior.
Regardless, I'm of the opinion that equating "extension" to "inheritance" is a code smell made popular by abuse of OOP. C++ has free functions. It's un-intrusive and allows you to work with the type and objects you really mean to work with. Furthermore, that protected member is still accessible if you are savvy:
bool is_greater(Base const& l, Base const& r) {
struct fetch : Base { using Base::a; };
return l.*(&fetch::a) > r.*(&fetch::a);
}
We define a local class that inherits from Base, yes. But we don't do it to mess around with objects of the wrong type. All it does is make the member accessible to us. Then we simply use pointer-to-member syntax to access that member on our Base objects in a well-defined manner.

Implementation of protected / private inheritance in compiler

If a class derives from another class like
class B{};
class D : private B{};
then I can not create derived class objects like:-
B* ptr = new D;
If I check the assembly difference of this code vs assembly code of class D deriving
from class B publically, I don't find any differnce.
Can anyone explain exactly how and at what stage the complier is differentiating between public / protected and private inheritance.
The compiler checks protection (public/private) in the frontend while parsing your code. Once it gets to the optimizer and code generation they are gone.
private means: "Can only be accessed from within the class or friends of the class"
Private inheritance is the same as public inheritance; but there are restrictions on which code that can access the fact that D is inherited from B. Since you can do all the same things with private inheritance as with public inheritance (but only in a limited scope), it makes sense that the two implemented in an identical way.
Your claim that you can't make derived classes with B* ptr = new D; is only true if you are not in the scope of D; for example, this works:
class B{};
class D : private B{
public:
void makeB() {
B* ptr = new D;
}
};
The compiler just parse the language and make sure that you do not break the rules.
It then goes on to produce some machine code (maybe via assembly language).
As long as you have not broke the rules of C++ it is free to do the implementation in machine code.
So at that stage private/public/protected or whatever does not matter. Higher up the chain you have been protected
The compiler checks the access, and gives a compilation error, if the base class is inaccessible. There is no need to emit different code to the executable.
There are cases where different code may be emitted (e.g. use of RTTI, dynamic_cast, etc which do runtime type checks) but you're not using that in this case.
Incidentally,
B* ptr = new D;
can be performed in a function that is a member or friend of D.
You are wrong. You certainly can create objects:
D* pd = new D;
You can't, however, cast a D object to the base B type, because of its 'private' scope.
You can see it, for example, with this code:
D d; // created successfully
B *pd = & d; // forbidden
B &pb = d; // forbidden
The messages are clear:
'type cast' : conversion from 'D *' to 'B *' exists, but is inaccessible
'type cast' : conversion from 'D *' to 'B &' exists, but is inaccessible
which means object D d exists and it can be seen as type B, it just can not be accessed in this context.
That's why you do not see any difference in assembly: operations which are allowed, look the same in both cases, what's different is that some operations are not allowed.

Why am I getting the error "A is an inaccessible base of B" when using dynamic_cast and templates?

Why is the call to f not resolving to the first function overload? I get the error:
source.cpp: In function 'int main()':
source.cpp:12:31: error: 'A' is an inaccessible base of 'B'
class A {}; class B : A {};
void f(const A &) { std::cout << "const A &"; }
template <typename T> void f(T) { std::cout << "Generic"; }
int main() {
B b;
f(dynamic_cast<const A &>(b));
}
Note that if I take out the dynamic_cast the code will work yet the second f is called (it prints "Generic"). But what I'm trying to do is to get the first call. I figured a dynamic_cast would work, but for some reason it causes problems. What am I doing wrong here?
The default class inheritance is private (class B : A {}; defaults to class B : private A {};).
So you can't handle b through type A.
EDIT:
Like Rob said :), the way to fix it is by using public inheritance:
class B : public A {};
EDIT:
The relationship between a publicly derived class and its base class is "is a", meaning that it is a specialization of a more generic type, and as such, it implements the behavior of that generic class and possibly more.
The relationship between a privately derived class and its base class is "implemented in terms of". It prevents objects from being considered extensions of the base class. A good example of its use is boost::noncopyable that prevents objects of a privately derived class from being copied.
http://www.boost.org/doc/libs/1_52_0/libs/utility/utility.htm#Class_noncopyable
In the hypothetical case that the requirements include private inheritance and at some point a function is created that wants to reference the object as its base, a public method returning a casted to base class pointer this will do it much like a traditional get() accesses a private data member maintaining the original purpose.
public:
A *getBase() { return static_cast<A *>(this); }
And then accessed like this:
f(b.getBase());
A is a private base of B, so there are very few places where an object of type B can be treated as an A&. If you change the inheritance to public the cast will work, and select the non-template version of f. But dynamic_cast is overkill; every object of type B is an object of type A, so you can use static_cast to disambiguate the call.
There's nothing special about dynamic_cast when it comes to upcasts. dynamic_cast is equivalent to static_cast in such cases. It is performed at compile-time if the base exists, is unambiguous and is accessible. It fails to compile otherwise.
This is exactly what happens in your case. The base is inaccessible (as the compiler told you already) so the cast fails to compile.
Without the cast the first function is excluded from the overload resolution candidate list (since the base is inaccessible), and the second one wins.
In fact, you don't really need any cast to perform legal upcasts in overwhelming majority of cases. As for illegal upcasts, no C++ cast will help you with that (the only cast that can "break through" private inheritance is C-style cast.)
It will fail because of the private inheritance, as mentioned, and because b is passed as an object. dynamic_cast will only work for pointers and references.
See: http://www.cplusplus.com/doc/tutorial/typecasting/

Pointer to base class and private inheritance

The following simple example will produce a compiler error, since I accidently use private inheritance:
main.cpp:21: error: ‘A’ is an inaccessible base of ‘B’
class A
{
};
class B : /*ups forgot that -> public*/ A
{
};
int main(int , char *[])
{
A* test = new B;
return 0;
}
Could you help me and explain what exactly is inaccessible in the base class and why it is needed in the conversion from B* to A*?
Private inheritance means that for everyone except B (and B's friends), B is not derived from A.
Could you help me and explain what exactly is inaccessible in the base class and why it is needed in the conversion from B* to A*?
Ouside of B and the friends of B, the simple fact that B is an A is not visible. This is not hiding a member variable or member function, but hiding the relationship itself. That is why from main you cannot bind the result of new B with a pointer to A, because as far as main is concerned, B is not an A (in the same way that you could not do A * p = new unrelated;)
As to why it is needed, the answer it exactly the same: because without access to the relationship, the compiler does not know (well, it knows, but will not tell you) how to obtain a pointer to the A subject inside B, because as far as it can see within that context there is no relationship between A and B at all.
The conversion from B* to A* is inaccessible, because the base-class subobject is private. When you convert B* to A*, you return the pointer to the base-class subobject. The latter must be accessible for the conversion to be accessible. In any function that is friend to B the conversion becomes accessible. By the way, you can always access the conversion by an explicit cast.
A* p = (A*)(new B);
Note that in some cases just accessible conversion is required, but in some cases it is required that A be a public (stronger than accessible) base of B. For example, when you try to catch an exception of type B with catch(A&) - it is required that A be a public base class of B.
Since the reference or pointer of Base class can not point to object of inherited class, does it mean that protected and private inheritance is nothing to do with polymorphism?
Since B is inherited from A, the default constructor of A would be called before the constructor of B. But because it is private and not inherited to B, you get a compiler error.
Public/private inheritance is equivalent to public/private member variable.
The result of the conversion is a reference to the base class subobject of the derived class object.
I think the accessibility means the accessibility of the base class subobject of the derived class object.For client,only if we ues public inheritance,the base class subobject is accessible.For the member function of derived class,no matter we use public/protected/privaye inheritance, the base class subobject is accessible.
class A{
};
class B: private A{
private:
int* m_pb;
public:
B(){m_pb=new int(10)};
void func()
{
A* pa= new B; //OK
int *pmb = m_pb; //OK
}
};
int main()
{
B* pb = new B;
A* pa= pb; // inaccessible
int *pmb = pb->m_pb; // inaccessible
}
OK.I means that public/private inheritance is equivalent to public/private member variable.
reference:
http://pic.dhe.ibm.com/infocenter/ratdevz/v8r5/index.jsp?topic=%2Fcom.ibm.tpf.toolkit.compilers.doc%2Fref%2Flangref_os390%2Fcbclr21011.htm

How to align pointers when dealing with multiple-inheritance?

Say we have a concrete class A, and an abstract class B.
Consider a concrete C, that inherits from both A and B, and implements B:
class C : public A, public B
{
/* implementation of B and specific stuff that belongs to C */
};
Now I define a function which signature is void foo(B* b);
This is my code, I can assume that every pointers to B are both A and B.
In foo's definition, how to get a pointer to A?
A nasty but working trick is to align back pointers like so:
void foo(B* b)
{
A* a = reinterpret_cast<A*>(reinterpret_cast<char*>(b) - sizeof(A));
// now I can use all the stuff from A
}
Keep in mind that C does not have a super type and actually, there are many classes akin to C which only are A and B. Feel free to question both my logic and this sample of design as well but the question is only concerning pointers alignment.
void foo(B* b)
{
//A* a = reinterpret_cast<A*>(reinterpret_cast<char*>(b) - sizeof(A)); // undefined behaviour!!!!
A* a = dynamic_cast<A*>(b);
if (a)
{
// now I can use all the stuff from A
}
else
{
// that was something else, not descended from A
}
}
Forgot to say: in order to make work dynamic cast both A and B should have virtual function(s) or at least virtual destructors. Otherwise there is no legal way to do that type conversion.
Having a huge set of unrelated classes that both derive from A and B is a very strange design. If there's something that makes A and B always be "used together" you could either merge them or introduce a shim class that only derives from them and then only derive from that class:
class Shim : A, B {};
class DerivedX : Shim {};
and in the latter case you just use static_cast to first downcast from A or B to Shim* and then C++ it will implicitly convert the Shim* pointer to the other class.
If you want to use the functionality of both class A and Class B in your function then you should modify the function to receive C pointers:
void foo(C* c);
And in general you are wrong with you assumption that "every B is an A as well". You could create classes derived from you B interface and not derived from Class A, that's why the compiler won't know that in your specific case "every B is an A".
Expanding on sharptooth's answer (and entering it as an answer, because I can't get formatted code into a comment), you can still use the shim:
class Shim : public virtual A, public virtual B {};
Then:
class Derived1 : public Shim, public virtual A, public virtual B1
{
};
class Derived2 : public Shim, public virtual A, public virtual B2
{
};
B1 and B2 must derive virtually from B.
But I suspect that if you always need to implement both A and
B, you should create a single interface with both, either by
inheriting, or coalising both into a single class; your B1 and
B2 would inherit from that. (The solution with
dynamic_cast, of course, is for the case where the derived
class of B may or may not also derived from A.)