b_vishwajit
asked on
Vritual functions casting from base class to derived class (Easy for experienced programmers)
This is the structure of my program:
class A
{
private:
//some private fields here.
public:
//constructors
//some functions
virtual void printObj();
}
//define printObj() here
class B:public class A //public inheritance
{
private:
//instance varibales.
public:
//
void printObj();
}
main()
{
A arrayOFA[size];
if(type A)
{
//call the parent virtual function
}
else if(type B)
{
//call virtual function from child class
//I have problems here
}
}
In my main program I am giving the user option to enter an object of Type A or B into the array. I then just assign object of type b to an array position. B has some extra private members other than parent class. Hence printObj() function is slightly different for class B.
Now I have flags to determine what kind of object an array position holds. Then after checking the flag I just want to call the appropriate printObj() function. If the object is of type A then I have no problems calling the parent class function. But if its of type
B how do it? I tried to use static_cast and tried to cast the object in the array to type B (i.e. parent to child class casting). But I got some weird errors. Whats the appropriate way to do it? Any good experts around here.............
Thanks in advance.
class A
{
private:
//some private fields here.
public:
//constructors
//some functions
virtual void printObj();
}
//define printObj() here
class B:public class A //public inheritance
{
private:
//instance varibales.
public:
//
void printObj();
}
main()
{
A arrayOFA[size];
if(type A)
{
//call the parent virtual function
}
else if(type B)
{
//call virtual function from child class
//I have problems here
}
}
In my main program I am giving the user option to enter an object of Type A or B into the array. I then just assign object of type b to an array position. B has some extra private members other than parent class. Hence printObj() function is slightly different for class B.
Now I have flags to determine what kind of object an array position holds. Then after checking the flag I just want to call the appropriate printObj() function. If the object is of type A then I have no problems calling the parent class function. But if its of type
B how do it? I tried to use static_cast and tried to cast the object in the array to type B (i.e. parent to child class casting). But I got some weird errors. Whats the appropriate way to do it? Any good experts around here.............
Thanks in advance.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
What do you mean by concrete types?
It is an array of type A and I am inserting type B which is of type A into the array. So when I want to retrieve B from the array how do I do it? Is there no way of doing this without using pointers?
It is an array of type A and I am inserting type B which is of type A into the array. So when I want to retrieve B from the array how do I do it? Is there no way of doing this without using pointers?
A arrayOFA[size];
vector<A*> MyArrayOfPointersTo_A_Type
i f(type A)
{
//create A type
MyArrayOfPointersTo_A_Type
}
else if(type B)
{
//create B type
MyArrayOfPointersTo_A_Type
}
//Later in your code, you don't have to check what type you have.
Just call the member function, and it will select the right derive member function.
MyArrayOfPointersTo_A_Type
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
>> What do you mean by concrete types?
May I ask why you are not giving any reaction to my post?
May I ask why you are not giving any reaction to my post?
ASKER
jkr I will try your solution and get back to you. It looks like it makes sense.
Example code:
class A
{
public:
A(int x):m_x(x){}
virtual int GetData(){return m_x;}
protected:
int m_x;
};
class B : public A
{
public:
B(int x, int y):A(x), m_y(y){}
int GetData(){return m_x + m_y;}
private:
int m_y;
};
int main(int argc, char* argv[])
{
B b(1, 2);
A a1 = b;//This compiles, but a loose properties of b
cout << a1.GetData() << endl;
A *a2 = new B(3, 4);//Compiles and retains properties of B
cout << a2->GetData() << endl;
// A a3 = new B(3, 4);//Does not compile
return 0;
}
class A
{
public:
A(int x):m_x(x){}
virtual int GetData(){return m_x;}
protected:
int m_x;
};
class B : public A
{
public:
B(int x, int y):A(x), m_y(y){}
int GetData(){return m_x + m_y;}
private:
int m_y;
};
int main(int argc, char* argv[])
{
B b(1, 2);
A a1 = b;//This compiles, but a loose properties of b
cout << a1.GetData() << endl;
A *a2 = new B(3, 4);//Compiles and retains properties of B
cout << a2->GetData() << endl;
// A a3 = new B(3, 4);//Does not compile
return 0;
}
ASKER
jkr. Though your solution looks conceptualy correct in my program pb->printObj(); still invokes the printObj() from the parent class.
Why is that? You should note this while adding type B to array of type A I am not doing any type casting. Type B can be added to array of type A without any problems since type B is of type A(inheritance). But while doing that am I loosing member fields of type B. I think I should not. What do you say? Reply ASAP.
Why is that? You should note this while adding type B to array of type A I am not doing any type casting. Type B can be added to array of type A without any problems since type B is of type A(inheritance). But while doing that am I loosing member fields of type B. I think I should not. What do you say? Reply ASAP.
You'll notice that a2->GetData() calls the correct function.
You don't need to determine what type you have for this to work.
That's how virtual functions should be used.
You don't need to determine what type you have for this to work.
That's how virtual functions should be used.
B* pb = (B*) &arrayOFA[someindex];
The above is not portable for concrete types, and will result in undefined behavior at best.
The above is not portable for concrete types, and will result in undefined behavior at best.
ASKER
>>A a1 = b;//This compiles, but a loose properties of b
Yup. I was thinking exactly the same way. So I cannot avoid pointers in any manner..
Yup. I was thinking exactly the same way. So I cannot avoid pointers in any manner..
Example code for your requirements:
class A
{
public:
A(int x):m_x(x){}
virtual int GetData(){return m_x;}
protected:
int m_x;
};
class B : public A
{
public:
B(int x, int y):A(x), m_y(y){}
int GetData(){return m_x + m_y;}
private:
int m_y;
};
int main(int argc, char* argv[])
{
vector<A*> arrayOFA;
arrayOFA.push_back(new A(1));
arrayOFA.push_back(new B(1, 3));
cout << arrayOFA[0]->GetData() << endl;
cout << arrayOFA[1]->GetData() << endl;
class A
{
public:
A(int x):m_x(x){}
virtual int GetData(){return m_x;}
protected:
int m_x;
};
class B : public A
{
public:
B(int x, int y):A(x), m_y(y){}
int GetData(){return m_x + m_y;}
private:
int m_y;
};
int main(int argc, char* argv[])
{
vector<A*> arrayOFA;
arrayOFA.push_back(new A(1));
arrayOFA.push_back(new B(1, 3));
cout << arrayOFA[0]->GetData() << endl;
cout << arrayOFA[1]->GetData() << endl;
>>Yup. I was thinking exactly the same way. So I cannot avoid pointers in any manner..
Not for this requirement.
You have to use pointers to access derive type virtual functions from a base type.
Not for this requirement.
You have to use pointers to access derive type virtual functions from a base type.
ASKER
I was trying to do this within a switch statement:
A* aPtr=new B(args); I got the following error from the compiler:
crosses initialization of `StudentRecord*srPtr'
crosses initialization of `A* aPtr'
What the heck is that supposed to mean?
A* aPtr=new B(args); I got the following error from the compiler:
crosses initialization of `StudentRecord*srPtr'
crosses initialization of `A* aPtr'
What the heck is that supposed to mean?
ASKER
>>crosses initialization of `StudentRecord*srPtr'//Ign ore this line.
//Actual error
jump to case label
crosses initialization of `A* aPtr'
//Actual error
jump to case label
crosses initialization of `A* aPtr'
Are you sure your B class is derived from A class?
And does your B class take the args type?
And does your B class take the args type?
Ned to see more code.
ASKER
Anyway I have an array of type A in my program and I want to stick with it. Doe anyone have any solution for this problem?
I will have to change my whole program structure if use array of pointers. I dont want to do it.
I will have to change my whole program structure if use array of pointers. I dont want to do it.
ASKER
Are you sure your B class is derived from A class?
And does your B class take the args type?
Yes.
In my program I have 4 classes in total. If post my code here its all gonna be messy and I dont want to do that.
And does your B class take the args type?
Yes.
In my program I have 4 classes in total. If post my code here its all gonna be messy and I dont want to do that.
Can you uploaded to a website?
ASKER
I can do that but it will be there only for 10 to 15 minutes. Just check the thread after 2 or three minutes. I will post the link here.
You can create an array of pointers without using vector.
Example:
int main(int argc, char* argv[])
{
A* arrayOFA[2] = {0};
arrayOFA[0] = new A(1);
arrayOFA[1] = new B(1, 3);
cout << arrayOFA[0]->GetData() << endl;
cout << arrayOFA[1]->GetData() << endl;
Example:
int main(int argc, char* argv[])
{
A* arrayOFA[2] = {0};
arrayOFA[0] = new A(1);
arrayOFA[1] = new B(1, 3);
cout << arrayOFA[0]->GetData() << endl;
cout << arrayOFA[1]->GetData() << endl;
ASKER
Just do it quickly.
http://www.ug.cs.sunysb.edu/~bhadrasv/
Download the "tmpsrc" folder. I cant keep it there for a long time.
http://www.ug.cs.sunysb.edu/~bhadrasv/
Download the "tmpsrc" folder. I cant keep it there for a long time.
ASKER
Axter I know I can do that. But I will have to redesign my whole program all over again. Is there any way of doing it just using an array of type A objects. Thanks.
>>using an array of type A objects
No
No
ASKER
Let me know when you r done downloading. I have to remove it.
ASKER
Ok I willl follow up on this 2mmorrow. I will decide whehther I want to use an array of pointers (probably I am not gonna do that).
Thanks any way Axter for trying.
Thanks any way Axter for trying.
Sorry, I just got back.
I'll be here for about 15 more minutes if you want to put it backup again.
I'll be here for about 15 more minutes if you want to put it backup again.
ASKER
Sorry for the delay. I was just not paying attention for a while.
A arrayOFA[size]; //This is an array of concrete types
If you want to have derive types in your array, then you need to create an array of pointers to your base type.