[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 206
  • Last Modified:

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.
0
b_vishwajit
Asked:
b_vishwajit
  • 14
  • 14
  • 2
2 Solutions
 
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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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
 
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

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 14
  • 14
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now