multi-inherit and pointer to pointer

H

homecurr

Here is my code

Class A;
Class B;
Class C : public A, public B
{
....
}

Class D {

C** GetC(){
C** ppC = ...
return ppC;
}
}

Class E{

void Compute(const B* const* ppB){
...
}
}


int main()
{
D d = new D();
C** ppC = d.GetC();

E e;
e.Compute(ppC); //***
}

With VC++ 6.0 the last line with //*** does not compile. If I change that to

e.COmpute((const B* const*)ppC);
The data is not passed correctly in the "Compute". How can I fix it?

Thanks,

John
 
V

Victor Bazarov

Here is my code

Class A;

class A {};

class B {};
Class C : public A, public B

class C ...
{
...
} ;


Class D {

class D {
public:

C** GetC(){
C** ppC = ...
return ppC;
}
} ;


Class E{

class E {
public:

void Compute(const B* const* ppB){
...
}
}


int main()
{
D d = new D();
C** ppC = d.GetC();

E e;
e.Compute(ppC); //***
}

With VC++ 6.0 the last line with //*** does not compile. If I change that to

e.COmpute((const B* const*)ppC);
The data is not passed correctly in the "Compute". How can I fix it?

You can't. Conversions 'derived -> base' are only defined for pointers
and references, but not pointers to pointers. Why do you need a pointer
to pointer, anyway? What are you trying to accomplish?

Victor
 
J

JKop

Victor Bazarov posted:
You can't. Conversions 'derived -> base' are only defined for pointers
and references, but not pointers to pointers.

Interesting. I don't see why it can't be done though.


-JKop
 
J

John Harrison

JKop said:
Victor Bazarov posted:


Interesting. I don't see why it can't be done though.

Because it would be dangerous, if it were allowed it would let you treat a
base object as a derived object. It the same reasoning that doesn't let you
convert T** to const T**.

struct B {};
struct D : B { void func(); };

B x;
D* p;
B** q = &p; // conversion from D** to B**, this is not allowed
*q = &x; // now p is pointing at x
p->func();

Converting from D** to B** has allowed us to call func() on x!

This code is adapted from FAQ 18.15

http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.15

john
 
J

JKop

posted:
Here is my code

Class A;
Class B;
Class C : public A, public B
{
...
}

Class D {

C** GetC(){
C** ppC = ...
return ppC;
}

I'd rename this to GetPointerToPointerToC

Why are you using pointers to pointers to objects, as opposed to pointers to
objects?
}

Class E{

void Compute(const B* const* ppB){
...
}
}


int main()
{
D d = new D();

This shouldn't compile. The left operand is of type "D". The right operand
is off type "D* const". It should be either:

D d = *(new D());

D& d = *(new D());

D* p_D = new D();

C** ppC = d.GetC();

E e;
e.Compute(ppC); //***
}

e.COmpute((const B* const*)ppC);
The data is not passed correctly in the "Compute". How can I fix it?

I myself amn't too familiar with multiple inheritence. But I can assure you
that your above cast is diastrous. You want to supply the function with a
pointer to a pointer to a B object. Using the cast, you're supplying it with
a pointer to a pointer to a C object.

Again I must enquire why the hell you're using pointers to pointers to
objects.


-JKop
 
T

tom_usenet

Here is my code

Class A;

Since when did class have an uppercase c?
int main()
{
D d = new D();
C** ppC = d.GetC();

E e;
e.Compute(ppC); //***

B* b = *ppC;
e.Compute(&b);
With VC++ 6.0 the last line with //*** does not compile. If I change that to

e.COmpute((const B* const*)ppC);
The data is not passed correctly in the "Compute". How can I fix it?

You can't convert a C** to a B**, so do the above.

Tom
 
F

Francis Glassborow

Here is my code

Class A;
Class B;
Class C : public A, public B
{
...
}
And there is your problem, base classes have to have been defined, a
(forward) declaration is not enough.
 
L

llewelly

Francis Glassborow said:
And there is your problem, base classes have to have been defined, a
(forward) declaration is not enough.
[snip]

Maybe not. I suspect the OP's real problem was that a C** couldn't be
converted to a B const*const* . But I can't really tell; the code
he posted was so full of errors - like 'Class', like the one you
point out, etc, that I finally gave up trying to figure out what
the problem was.
 
K

kanze

Victor Bazarov posted:

That's not strictly true. I think he forgot the word "implicite". The
standard defines four types of conversions on pointers, and
reinterpret_cast IS allowed for pointers to pointers. Only a subset of
static_cast and const_cast conversions will occur implicitely, however.
Interesting. I don't see why it can't be done though.

And how would you propose implementing it? Keeping in mind that the
address of the base part of an object might not be the same as the
address of the derived part. If I have the following:

Base ** ppb ;
Derived * pd ;
*ppb = pd ;

the compiler knows to adjust the address so that the assigned address
points to the base part of my object. If instead of Base ** ppb, I had
written Derived ** ppd, the compiler would know that no adjustment is
necessary. Except that if *ppd is actuall a Base*, adjustment IS
necessary.

This is why the original poster's example crashed when he used an
explicit conversion. The explicit conversion was a reinterpret_cast,
which lied to the compiler. And when you're talking to a compiler,
lying definitly doesn't pay.
 
J

JKop

posted:

And how would you propose implementing it? Keeping in mind that the
address of the base part of an object might not be the same as the
address of the derived part. If I have the following:

Base ** ppb ;
Derived * pd ;
*ppb = pd ;

the compiler knows to adjust the address so that the assigned address
points to the base part of my object.

No it doesn't. That's exactly what I'm talking about.

The compiler *can* work with the following:


class Derived : public Base1, public Base2 { ...

Derived derived;

Base2* p_base2 = &derived; //Here it will return what you want - the pointer
to where the Base2 object starts.


But... what doesn't work is:


Derived derived;

Derived* p_derived = &derived;

Base2** = &p_derived;



-JKop
 
K

kanze

JKop said:
No it doesn't. That's exactly what I'm talking about.

But of course it does. This is nothing more than a classical Derived*
to Base* conversion. Surely you aren't saying that a Derived* to Base*
isn't guaranteed to work, or is illegal.
The compiler *can* work with the following:
class Derived : public Base1, public Base2 { ...
Derived derived;
Base2* p_base2 = &derived; //Here it will return what you want - the pointer
to where the Base2 object starts.

So what is the difference compared to my example? Instead of pd (a
Derived*), you use &derived (a Derived*); instead of *ppb (a Base*), you
use p_base2 (a Base*). The types in the assignment expression are the
same. We both assign a Derived* to a Base*.
But... what doesn't work is:
Derived derived;
Derived* p_derived = &derived;
Base2** = &p_derived;

Of course not. That's my point. If you do this, the compiler must be
able to cope with the fact that what the Base2** points to might be a
Derived*. Then, when you assign a Derived* to whatever the Base2**
points to, the compiler has no way of knowing that what the Base2*
points to is really a Derived* (and not a Base2*), so it applies the
fixup, although it shouldn't.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top