2

Here's my problem: I want to subclass QVector in order to add some function specific to my context.

Naive approach was:

class ClassVector : public QVector<Class> { ... }

But problem here is when I need to call one of few functions on QVector which return new QVector (or & to itself):

ClassVector cv1, cv2;
auto sum = cv1 + cv2;

This is valid but sum is QVector, since operator+ return QVector.

Is there simple way to make it return ClassVector somehow?

Calling reinterpret_cast on the result is not what I want to do :/

If it's important, I only add functions to ClassVector, no data members.

Thanks for help.

graywolf
  • 7,092
  • 7
  • 53
  • 77
  • 4
    I don't know about QVector, but not all classes are meant to be inherited. Can you add your functions as free-standing (or in a namespace)? Especially if you only add functions, and it has no virtual functions. – Neil Kirk Sep 23 '14 at 12:57
  • 3
    I'd recommend against subclassing `QVector`. Could you add your functions as free functions instead, since you apparently don't need to add state to the class? Alternatively, could you create your new class with a `QVector` as a member instead of a super class (this is called aggregation)? – Magnus Hoff Sep 23 '14 at 12:58
  • Yeah, that's what I'm currently doing (free functions in namespace) but I was curious if there isn't any smarter way of doing this.. seems that it isn't :/ – graywolf Sep 23 '14 at 13:11
  • @Paladin [See also this question, which, while about C#, also applies to your scenario](http://stackoverflow.com/questions/21692193/why-not-inherit-from-listt) – milleniumbug Sep 23 '14 at 13:18
  • @milleniumbug ok, it sort of applies to my scenario, but not completely. OP over there asks if he should implement football team as subclass of list while he wants to add new data to the class (score, ...). That's not my case. I only want to add few convenience functions (for example for QVector searching for item in vector by Class.foo). All of those are definitely doable by non-member functions, I just though it would be handy to have them directly on the vector.. – graywolf Sep 23 '14 at 14:30

1 Answers1

2

If the new operator+ shall return a different type, you can of course re-implement it.

#include <QVector>
#include <iostream>

class ClassVector : public QVector<int>
{
public:
    typedef QVector<int> base_type;

    ClassVector operator+ (const ClassVector& other) const
    {
        ClassVector sum(*this);
        static_cast<base_type&>(sum) += other;
        return sum;
    }
};

int main()
{
    ClassVector cv1;
    cv1.append(1);
    cv1.append(2);
    cv1.append(3);
    ClassVector cv2;
    cv2.append(11);
    cv2.append(12);

    ClassVector sum = cv1 + cv2;

    for (auto&& v : sum)
        std::cout << v << std::endl;
}

Another option would be to have an implicit constructor for the conversion from QVector<Class> to ClassVector. Something like

class ClassVector : public QVector<int>
{
public:
    typedef QVector<int> base_type;

    ClassVector() {}

    // Allow to convert a QVector<int> into a ClassVector.
    ClassVector(const QVector<int>& other) : QVector<int>(other) {}

    // ... possibly other constructors + assignment operator
};

would also work in your case.

However, if you do not add new state to ClassVector, I would also go with a free function.

Mehrwolf
  • 8,208
  • 2
  • 26
  • 38
  • Can I also override __non-virtual__ functions like this? – graywolf Sep 23 '14 at 14:25
  • Note that the example above has no virtual function in it. As long as you do not operate via a base class pointer (or reference), you can also overload non-virtual functions. – Mehrwolf Sep 23 '14 at 16:01
  • ok, thanks for the help :) I'm going with free functions, it just seems cleaner (and safer) – graywolf Sep 24 '14 at 06:44