reinterpret_cast vector of derived class to vector of base class

461 views Asked by At

I have a 3rd-party class, say, class A, and a function accepting vector of class A from the same 3rd-party, say f3() (See simplified program below).

For easier use of A, I created a derived class B. Many part of my program used class B.

The question is, how can I call f3() with a vector of B as its argument? Is a forced casting in the argument of f3() like the program below a good practice?

#include <vector>
#include <iostream>
#include <algorithm>

using namespace std;

// a 3rd-party class
class A
{
public:
    int n;
    void f1();
};

// my class
class B: public A
{
public:
    void f2();
};

// a 3rd-party function
void f3(std::vector<A> &a);

int main()
{
    std::vector<B> y;

    y.push_back(B());
    y.push_back(B());
    y.push_back(B());
    y.push_back(B());

    f3(*(vector<A>*)(&y));  // Is this a good practice?
    cout << y[3].n << endl;
    return 0;
}

Note that, for compatibility, I purposely make class B to have no more variables than class A, when B inherits from A. However, Class B does have more methods than A.

Will it guarantee that sizeof(A) is the same as sizeof(B), so that our cast of vector will work?

I am working on C++03

1

There are 1 answers

2
MichaelCMS On BEST ANSWER

To answer the question from your code :

No, it's actually a very bad practice , and it will lead to undefined behavior.

If sizeof(A) is equal to sizeof(B) your code might end up working ,considering that all functions derived in B and used inside f3 are virtual and non inline.

If you end up using such code , make sure you will never ever add another virtual function / member variable to the B class .

If you want a way to bypass this limitation (f3 third party function only accepts vector of A ) , try making B a composite rather then a derived (if you are not accessing protected members of A ) :

class A 
{
   public:
   int n;
   void f1();
}
class B
{
  public:
      B (const A& a); // dependency injection
      void f2();
      A  myA; // bad practice, should be private with getter /setter
}

This way you are isolating the A specific functionality / features.

Ofc you will still need to manually make a vector of A objects made from the objects contained in B (you cannot pass a vector of B).