Alejandro Sazo
Alejandro Sazo

Reputation: 795

Pass vector of inherited class object to function expecting base class vector

I am working with a class A, which inherits from opencv Rect. A just adds some variables I would like to keep track during execution.

class A: public Rect { //code, constructors... }

I want to use the opencv method detectMultiScale which expects an empty vector<Rect> and what does is fill it with the expected output.

How can I pass an empty vector of inherited objects, that's it the vector<A> from Rect and expect to catch the base class inside the method? (I understand at this point that the method is a black box, I don't want to compile opencv to redeclare something).

Upvotes: 3

Views: 1237

Answers (2)

lorro
lorro

Reputation: 10880

I'm afraid that won't work, you'll have to work with std::vector<Rect*> - intuitively, this follows when sizeof(Rect) != sizeof(A), so even your indexing will fail, let alone class layout, for std::vector<Rect>. Either pointers, or, if you have a fixed set of types, you can experiment with variant and visitors.

EDIT: If your use case (detectMultiScale) does not allow you to pass vector<std::Rect*>, you might choose from the various decorator-visitor implementations. In this case, you have to give up direct inheritance. To name some:

  • Have a std::vector<Rect> and a std::vector<ARectV>. ARectV contains the additional fields that you can't find in Rect.

    • you might add a ref to the corresponding (visited) Rect if you wish. In this case, the constructor will fill Rect; or
    • your ARectV methods might take a (possibly const) Rect&, in this case your constructor doesn't need to store it
  • If all else fails, have a static std::map<Rect*, ARectV> sARectV. This will be slower and needs manual insertion / deletion (possibly in constructors / destructor of sARectV, the former taking a - possibly const - Rect* or Rect&), but allows you to write: sARectV[&rect].yourfunction(). Of course, it also allows for standard notation, that is, Rect rect; ARectV rectv(rect); rectv.yourfunction(); - but you might not be able to pass rv to callbacks that should take Rect* or Rect&. If they take Rect by value, you're out of luck.

Upvotes: 1

eerorika
eerorika

Reputation: 238301

How can I pass an empty vector of inherited objects, that's it the vector from Rect and expect to catch the base class inside the method?

This is not possible. The function expects a vector of Rect objects, so that is what you must pass.

If you want to have a vector of A, then you can write a constructor A(Rect), that accepts an instance of the base class as an argument, and initializes the base sub object accordingly. Then write a loop that transforms the aquired Rect instances.

Upvotes: 1

Related Questions