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.
LVL 5
b_vishwajitAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jkrCommented:
What you could do is

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:
                      //
                       virtual void printObj();
}

main()
{
             A arrayOFA[size];

               if(type A)
               {
                        //call the parent virtual function
                }
                else if(type B)
               {
                        B* pb = (B*) &arrayOFA[someindex];

                        pb->printObj();
                }
                 
}
0
AxterCommented:
If you have an array of concrete types, you can't call a derive type from it.

 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.
0
b_vishwajitAuthor Commented:
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?
0
Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

AxterCommented:

A arrayOFA[size];

vector<A*> MyArrayOfPointersTo_A_Types;

i               f(type A)
               {
                        //create A type
                        MyArrayOfPointersTo_A_Types.push_back(new A());
                }
                else if(type B)
               {
                        //create B type
                        MyArrayOfPointersTo_A_Types.push_back(new B());
                }

//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_Types[0]->printObj(); //Will print correct member function.


0
AxterCommented:
>>It is an array of type A and I am inserting type B which is of type A into the array.
You can not insert type B into a concrete A type.

A a; //This is a declared concrete A type
A *a; //This is a declared pointer to A type

In order to assigned a derive type, you need a base type pointer.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
jkrCommented:
>> What do you mean by concrete types?

May I ask why you are not giving any reaction to my post?
0
b_vishwajitAuthor Commented:
jkr I will try your solution and get back to you. It looks like it makes sense.
0
AxterCommented:
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;
}
0
b_vishwajitAuthor Commented:
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.
0
AxterCommented:
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.
0
AxterCommented:
B* pb = (B*) &arrayOFA[someindex];

The above is not portable for concrete types, and will result in undefined behavior at best.
0
b_vishwajitAuthor Commented:
>>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..
0
AxterCommented:
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;
0
AxterCommented:
>>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.
0
b_vishwajitAuthor Commented:
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?
0
b_vishwajitAuthor Commented:
>>crosses initialization of `StudentRecord*srPtr'//Ignore this line.

//Actual error

 jump to case label

crosses initialization of `A* aPtr'
0
AxterCommented:
Are you sure your B class is derived from A class?
And does your B class take the args type?
0
AxterCommented:
Ned to see more code.
0
b_vishwajitAuthor Commented:
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.
0
b_vishwajitAuthor Commented:
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.
0
AxterCommented:
Can you uploaded to a website?
0
b_vishwajitAuthor Commented:
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.
0
AxterCommented:
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;
0
b_vishwajitAuthor Commented:
Just do it quickly.
http://www.ug.cs.sunysb.edu/~bhadrasv/
Download the "tmpsrc" folder. I cant keep it  there for a long time.
0
b_vishwajitAuthor Commented:
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.
0
AxterCommented:
>>using an array of type A objects
No
0
b_vishwajitAuthor Commented:
Let me know when you  r done downloading. I have to remove it.
0
b_vishwajitAuthor Commented:
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.
0
AxterCommented:
Sorry, I just got back.

I'll be here for about 15 more minutes if you want to put it backup again.
0
b_vishwajitAuthor Commented:
Sorry for the delay. I was just not paying attention for a while.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.