What are the benefits and drawbacks of using classes that only differ in their constructors?

I have a class SpecialArray which can be accessed in the same way as a standard two-dimensional array; i.e., as A[i][j]. It is frequently necessary to extract a one-dimensional array of int from this object. The details of the extraction, which depend on other passed parameters, are immaterial; I'm interested in designing the interface of the operation.

What are the benefits and drawbacks of the following approaches to accomplishing this task?

Option 1

We define a function:

std::vector<int> extract(const SpecialArray &A, ...)

where here ... refers to other parameters that determine the content of the one-dimensional array, and use it as:

std::vector<int> output = extract(A,...);

Option 2

We create a class that inherits from std::vector and constructs itself:

class SpecialArrayExtract : public std::vector<int> {
    public:
        SpecialArrayExtract(const SpecialArray &A, ...);
};

where the constructor (or, equivalently, an init function) uses the ... input to fill *this with the appropriate data, and we use it as:

SpecialArrayExtract output(A,...);

Option 3

We proceed exactly as in Option 2, but do not inherit from std::vector<int> and instead have a private member std::vector<int> with interface exposed as needed:

class SpecialArrayExtract {
    private:
        std::vector<int> m_data;
    public:
        SpecialArrayExtract(const SpecialArray &A, ...);
        [Wrapper functions for std::vector<int> here.]
};

Commentary

The application is high-performance, but with RVO in Option 1, I'm assuming these should all perform equivalently.

Tying this back into the title, the point I'm trying to get at is that both Options 2 and 3 define classes that are essentially just std::vector<int> with a different name and a special constructor. when -- if ever! -- is this a reasonable idea, and which is the better way to do it?

Answers


I believe option one makes the most sense because it:

  • has a trivially simple interface
  • does not create additional classes
  • can be extended via templates for other "extraction" operations

I am against option two because if you inherit from std::vector<int> you are saying that the SpecialArrayExtract is-a std::vector<int>, and provide a single operation (the constructor) to create it. If you think about it, it is just a convoluted way to do exactly the same as your first alternative.

Option three seems to be a premature optimization (you are opting for containment instead of inheritance, as if you would be preemptively expecting the underlying data container to change) which convolutes even more than alternative two.

As for the option four (suggested in an answer), I believe that a class interface should keep as few as possible instance methods, and instead offer non-member functions (refer to this article to learn the rationale).

If your needs were to change in the future (for example, you decide that another container or data type serves better your needs) you could modify the function via templates. This would give you all the advantages of having a separate class, but not the overhead. And the same operation (with the exact same name) could apply to any possible combination of ContainerTypes (i.e., std::vector<int>, or std::array<int, 12>, or whatever) and ArrayTypes (SpecialArray, or SparseSpecialArray, or whatever):

template<typename ContainerType, typename ArrayType>
ContainerType extract(const ArrayType& array, ...)

Finally, you could create a separate algorithms namespace with all the functions which act on ArrayType data (e.g, SpecialArray). This would make it very straightforward to document and maintain your code: all generic operations for your data type live in algorithms::, and a namespace is a much more natural aggregator for this kind of operation than, say, a class with many static methods.


Need Your Help

How to set connection timeout for volley?

android timeout android-volley

I know volley have a Retry Policy,but what i know , this is for a socket timeout,not for a connection timeout, Apache HttpClient have setConnectionTimeout and setSoTimeout Method,is anyone know if ...

What is a better design if two subclasses have the same method?

oop

Just as an example, if House is the base class, and Colonial is a subclass of House, and Colonial has a method that is goUpstairs. There is another class called Mansion which is also a subclass of