inheritence and functions

Started by
12 comments, last by Dragon_Strike 16 years, 3 months ago
ive got some problems with inheritence... ive got a class B which is inherited from A. And i have a function i would like to use B with but the function argument is A something like this

void Function( A** foo)
{
......
}

class B : public A
{
    public:
       B()
       {
          A* temp;
          
          Function(&temp);
 
          *this = *temp;
          
       }
}


this doesnt work ofcourse since B = A isnt defined... and which i cant define since i onyl have access to public members of A... is there anyway i can send B as an A in the function? how can i solve this?
Advertisement
Your problem looks similar to this.
Hmm, this is an odd looking situation. I'm not sure what the best way to solve it is, but I think it would be good to mention that relying on polymorphism within constructors and destructors is generally a bad idea in C++ (which it appears you're using).

It seems that your function is generating an A object from which you produce a B object. If so, why not just create an A (via the function) and have B objects accept an A object as a parameter to their constructor(s). Then, directly access the members of A you need in an initialization list. Remember, initialization is NOT the same as assignment, and it seems like a bad sign to me that you're doing a self assignment in a constructor.

If you need to use this pattern for some reason, perhaps a non-member assignment function that is a friend both A and B could work. The parameters could be an A object and a B object. (You could just use A parameters, but again it's dangerous to count on polymorphism in a constructor.)

Hope this is a bit helpful. Looks tricky.
Quote:this doesnt work ofcourse since B = A isnt defined... and which i cant define since i onyl have access to public members of A...


The compiler is smart. Listen to it.

Quote:how can i solve this?


How about using the constructors?

struct A {  A();public/protected:  // construct A using function f's transform  A( void (*f)(A**) )  {    f(&this);  }};


struct B : public/private/protected A {  B()    : A(&Function)  {}};


Although I'd prefer to know the real reason for this. I'm willing to bet there's a completely natural solution to this.
thx for the answer... gave me some ideas ill try...

anyways ill try to clear out a few things

the "Function" and "A" i cannot change in anyway since its predefined in a library...

and it isnt rly called in the constructor i only write it that way to make it simple...

this would be more correct...

void Function( A** foo){......}class B : public A{    public:       void Bar()       {          A* temp;                    Function(&temp);           *this = *temp;                 }}



what im rly trying to do is to add a few variables and function to the class A... one way to do this would be to define A as an variable (Var) in a class... but then every time i need to call something from A i have to use Var.Function... which isnt what i want... or i would have to rewrite every single fcuntion in A as an function in the new class... which isnt very pratical...
Is there a reason why Function has to take a pointer to a pointer? If there is the the following may work: have a function in A which calls the function itself passing the this eg
class A{protected:void call_func(){//can you take the address of this??Function(&this);//if not then use a temp//A* temp(this);//Function(&temp);}};class B : public A{    public:       B()       {          call_func();       }}


Edit "the "Function" and "A" i cannot change in anyway since its predefined in a library..."
How about

void Helper(A* a){Function(&a);}

is that valid?
[/source]
struct B : public A{	void boo()	{                // no problem here, we know we are A		A * a = static_cast<A*>(this);		Function( &a );	}};


Although I'm not sure if this doesn't break some hidden rule. Again, it depends on how your API and classes actually look like.

There might be a problem with empty member optimization though, depending on what Function actually does.
To me, a function prototype of the form void f(T**) just screams 'I will allocate or otherwise produce an object of type T, and return it by modifying the pointer I'm passed so that it points to that object'. For instance:
void f(A **a) {  *a = new A;}


So, I would be extremely wary (and so is the compiler) of passing a pointer-to-pointer-to-B inside such a function.
B *b;f(&b);// Now, b points to a 'new A'. Whoops.


Judging from your code, this is exactly what's happening. In short, you're using a function to create an A object, and wondering about how to convert it to a B once it's created. Well, to answer that, we obviously have to know what A and B are.
ill take that as there is no general solution...

the class i mean by A is the ID3DXEffect and the "Function" is D3DXCreateEffectFromFile, both defined in the directx sdk...

i dont see why this ( B = A) shouldnt be possible? couldnt in theory just assign all values in A to the correpsonding in B and then call the default constructor for B to initialize the rest... and then throw away A
Quote:Original post by Dragon_Strike
ill take that as there is no general solution...

the class i mean by A is the ID3DXEffect defined in the directx sdk...

i dont see why this ( B = A) shouldnt be possible? couldnt in theory just assign all values in A to the correpsonding in B and then call the default constructor for B to initialize the rest... and then throw away A


Quote:typedef interface ID3DXEffect ID3DXEffect;
typedef interface ID3DXEffect *LPD3DXEFFECT;


There's a reason why you obtain it by calling a function, and not new-ing it. What you obtain is part of arbitrary class instance - which one is something you don't know. Even more, assigning to such parts is impossible, or at least very bad, since they're not necessarily on top of hierarchy.

Make a class that has ID3DXEffect as a public member. It will have exactly the same effect as inheriting from one.

The problem you're facing here is actually this:
class A {}class A1 : public A {}class A2 : public A ()A * createA() <-- this is how you obtain an instance of A in your application{  return new A2(); // or any of Ax variations}class B : public A {};


How will A know what to assign when it has no members, and doesn't know which real class it belongs to?

Even more, B "implements" A, but doesn't extend A2, which is actual instance returned.

This topic is closed to new replies.

Advertisement