| | |
Multiple inheritance and cross-class type casting
Please support our C++ advertiser: Intel Parallel Studio Home
![]() |
•
•
Join Date: Nov 2008
Posts: 21
Reputation:
Solved Threads: 3
I have classes A1, A2, B, and C. A2 inherits from A1. C inherits from A2 and B, and its constructor initializes all B, A2, and A1 variables.
As a tree, it looks like this:
I have a function Foo that takes a parameter pointer P of type B*, but the only parameters passed will be of type C* (and thus their objects will have all B, A2, and A1 variables initialized)
Inside Foo, I can type cast my P into A2* or A1* pointers, and I'm able to use those functions. The A2 and A1 functions run without complaining, but none of the A2 or A1 variables get recognized (when I debug they're all uninitialized), which leads to bugs.
Can somebody explain why this happens and what I can do to fix it (I can't change Foo's parameter type), or direct me to a source where I can read more about it?
EDIT: when I say I'm explicitly casting my P into A2*, I mean I just do (A2*)P->bar(), so I may be using the wrong type of casting.
As a tree, it looks like this:
C++ Syntax (Toggle Plain Text)
C / \ B A2 | A1
I have a function Foo that takes a parameter pointer P of type B*, but the only parameters passed will be of type C* (and thus their objects will have all B, A2, and A1 variables initialized)
Inside Foo, I can type cast my P into A2* or A1* pointers, and I'm able to use those functions. The A2 and A1 functions run without complaining, but none of the A2 or A1 variables get recognized (when I debug they're all uninitialized), which leads to bugs.
Can somebody explain why this happens and what I can do to fix it (I can't change Foo's parameter type), or direct me to a source where I can read more about it?
EDIT: when I say I'm explicitly casting my P into A2*, I mean I just do (A2*)P->bar(), so I may be using the wrong type of casting.
Last edited by axfv; May 4th, 2009 at 2:14 pm.
It's hard to say without seeing your code, but I'd wager your cast is wrong. Compare your code with this skeleton and tell me if you're doing something equivalent:
C++ Syntax (Toggle Plain Text)
#include <iostream> class A1 { public: int a1; virtual ~A1() {} }; class A2: public A1 { public: int a2; virtual ~A2() {} }; class B { public: int b; virtual ~B() {} }; class C: public A2, public B { public: int c; }; void foo ( B* p ) { C *cp = dynamic_cast<C*> ( p ); if ( cp != 0 ) { std::cout<< cp->a1 <<'\n' << cp->a2 <<'\n' << cp->b <<'\n' << cp->c <<'\n'; } } int main() { C c; c.a1 = 1; c.a2 = 2; c.b = 3; c.c = 4; foo ( &c ); }
New members chased away this month: 3
•
•
Join Date: Nov 2008
Posts: 21
Reputation:
Solved Threads: 3
Unfortunately this code is for a proprietary application and the classes span several files, so the full code would be impractical to put up.
I was only using explicit type casting, but I started to use dynamic_cast, though it's returning type void*.
Also, I screwed up when I was describing my problem. Class B has a function Foo(), but it will only be used by objects type C. Inside Foo(), we attempt to cast the keyword this, so it's something like this:
I was only using explicit type casting, but I started to use dynamic_cast, though it's returning type void*.
Also, I screwed up when I was describing my problem. Class B has a function Foo(), but it will only be used by objects type C. Inside Foo(), we attempt to cast the keyword this, so it's something like this:
C++ Syntax (Toggle Plain Text)
... class B { void Foo() { C* thisC = dynamic_cast<C*>(this); //returns type VOID* } } ...
Last edited by axfv; May 4th, 2009 at 3:19 pm.
•
•
Join Date: Nov 2008
Posts: 21
Reputation:
Solved Threads: 3
ok, that was a good idea. I was able to narrow the problem down by creating a bare-bones example (took so long because I was hoping to find a fix myself):
stafx.h
InheritanceTest.cpp:
I had to split the function definition for B because it complained of referencing the non-yet-existent class C.
The output produced by cVar.Foo(5) is "1 \n 0", when I want it to be "1 \n 1". Casting inside B to (C*)this seems to preserve everything because it "casts up", but casting to (A2*)this messes up because it "casts across". I verified this in my real project and casting up did indeed preserve the object variables, while casting across no longer recognized their values.
In my real project, I'll need to cast across.
stafx.h
C++ Syntax (Toggle Plain Text)
#pragma once #include <iostream> #include <tchar.h> class A1 { int a1var; public: A1() {}; int getvar() { return a1var; }; void setvar(int n) { a1var = n; }; }; class A2 : public A1 { public: A2() : A1() {setvar(5);}; }; class B { public: B() {}; void Foo (int n); virtual Bar() {}; // dummy function to make this a polymorphic class }; class C : public A2, public B { public: C() : A2() , B() {}; };
InheritanceTest.cpp:
C++ Syntax (Toggle Plain Text)
#include "stdafx.h" using namespace std; void B::Foo (int n) { cout << (n==((C*)this)->getvar()) ? 1 : 0; cout << endl; cout << (n==((A2*)this)->getvar()) ? 1 : 0; }; int _tmain(int argc, _TCHAR* argv[]) { C cVar = C(); cVar.Foo(5); return 0; }
I had to split the function definition for B because it complained of referencing the non-yet-existent class C.
The output produced by cVar.Foo(5) is "1 \n 0", when I want it to be "1 \n 1". Casting inside B to (C*)this seems to preserve everything because it "casts up", but casting to (A2*)this messes up because it "casts across". I verified this in my real project and casting up did indeed preserve the object variables, while casting across no longer recognized their values.
In my real project, I'll need to cast across.
Last edited by axfv; May 4th, 2009 at 4:47 pm.
C-style casts are incorrect in that case: class B is_NOT_a C, A1 or A2.
It's impossible to use this construct in the definition of parent of C:
Class B do not know its descendants. Incomplete C declaration can't help in that case (C* type var is invalid target type for dynamic_cast with incomplete declaration of C). However you can place B::foo() implementation after definition of C (what's a strange inheritance: the parent must know its descendant).
This sceleton works fine:
It's impossible to use this construct in the definition of parent of C:
C++ Syntax (Toggle Plain Text)
class B { ... void foo() { C* p = dynamyc_cast<C*>(this); ... } ... };
This sceleton works fine:
C++ Syntax (Toggle Plain Text)
class A1 { public: A1():i(1001) {} virtual ~A1() {} virtual char const* who() const { return "A1"; } protected: int i; }; class A2: public A1 { public: A2():A1(),i(1002) {} char const* who() const { return "A2"; } protected: int i; }; class B { public: // must be polymorphic! virtual ~B() {} void foo() { C* pc = dynamic_cast<C*>(this); } }; class C: public A2, public B { public: C() { A1::i = 1; A2::i = 2; } char const* who() const { return "C"; } void show() const { cout << A1::i << ':' << A2::i; } }; void foo(const B* p) { const C* pc; pc = dynamic_cast<const C*>(p); if (pc) { cout << pc->who() << '\t'; pc->show(); cout << endl; const A1* pa1 = pc; cout << pa1->who() << endl; } else cout << "Don\'t know\n"; } int main() { C c; c.show(); cout << '\n'; foo(&c); return 0; }
Last edited by ArkM; May 4th, 2009 at 5:13 pm.
![]() |
Similar Threads
- casting from userData (C++)
Other Threads in the C++ Forum
- Previous Thread: C++ and the internet??
- Next Thread: Regex Split problem, probably a no brainer.
| Thread Tools | Search this Thread |
Tag cloud for C++
api application array arrays based beginner binary bmp c++ c/c++ calculator char char* class classes code coding compile compiler console conversion convert count data database delete deploy developer display dll dynamiccharacterarray email encryption error file format forms fstream function functions game generator givemetehcodez graph homeworkhelp iamthwee ifstream image input int java lib list loop looping loops map math matrix memory multiple newbie news number numbertoword output pointer problem program programming project python random read recursion recursive reference return rpg simple sorting spoonfeeding string strings struct template templates text tree url variable vector video visual visualstudio win32 windows winsock wordfrequency wxwidgets






