3

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

Robin Hsu
  • 4,164
  • 3
  • 20
  • 37

1 Answers1

2

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

MichaelCMS
  • 4,703
  • 2
  • 23
  • 29
  • Yes, I plan to use B from A without any virtual functions, any more variables. But why inline matters? I think inline member functions mean codes, not storage, and thus the vector should be compatible... – Robin Hsu Jun 16 '15 at 10:23
  • inline virtual functions might end up inlining from A . Also depending on what the function does behind, you might end up with slicing . This are general bad things that could happen if you use the approach you mentioned . You should test if what you proposed works fine for your project, but even if it does, you should keep in mind in the future why these approaches are bad. – MichaelCMS Jun 17 '15 at 10:26