Specialization or/and inheritance

Pages: 12
Mar 11, 2011 at 2:06pm
Hello

I use vector as dynamic array. If I need my own specific methods for vector<MyType> can I make a specialization or I can only do it with inheritance creating a new class, say
1
2
3
4
class MyTypeVector : public std::vector<MyType>{
public:
  void doSomething();
}

If it can be done through specialization would you please give a short code example.
Last edited on Mar 11, 2011 at 2:06pm
Mar 11, 2011 at 2:57pm
Specialisation is inheritance. Do you mean aggregation?
Mar 11, 2011 at 3:08pm
Last edited on Mar 11, 2011 at 3:08pm
Mar 11, 2011 at 3:18pm
I've read about aggreagation, but as I understood it, I don't think it's about that. I'll try to explain a little...

What I would like to be able to do is:
1
2
3
vector<MyType> x;
x.resize(5);  // use vector function
x.doSomething(); // use my function 


Question is: Is there a way I can do that without creating a new class ?

If I use the the code from first post then I'll be able to do it like that:
1
2
3
MyTypeVector x;
x.resize(5);
x.doSomething();
Last edited on Mar 11, 2011 at 3:19pm
Mar 11, 2011 at 3:20pm
In C++ you can't add new methods to existing classes.
You can do that in dynamic languages (e.g. Ruby, Python, Scala).
Mar 11, 2011 at 3:38pm
You can write a function:

doSomething(x);
Mar 11, 2011 at 4:24pm
By SPECIALIZATION I mean Template Specialization. I thought there's a way to do what I need using template specialization
Mar 11, 2011 at 4:35pm
Your best option is to write a class that contains a vector and forward all of the methods appropriately. Best meaning: safest and most maintainable (less coupling). Unfortunately, this is still a lot of work.
Mar 11, 2011 at 4:42pm
Do you just want to tack on one function or is your type much bigger than a vector?

The article posted by filipe above shows how to create one off template functions from stardard components. If you want to add just a few functions, that's a reasonable approach.
Mar 11, 2011 at 5:11pm
what filipe said is a procedural approach let's say sort(MyVector)... An OOP approach is MyVector.sort();

I would like to have an OOP approach. If eventually I want to sort ascending and descending I would need to write 2 functions in a procedural approach and more code, while I would write less in 1 function say ... MyVector.sort("asc");

At the start, YES, there will be just a few functions, but growing it will be messier, and that's what I really don't want

So in the end, if I don't get a better idea I think I'll either inherit or use moorecm's advice.
Thank you, moorecm
Last edited on Mar 11, 2011 at 5:14pm
Mar 11, 2011 at 5:19pm
moorecm's method is aggregation.

Of course, only you know what your object model is, so I don't think there's any further to add.
Mar 11, 2011 at 5:53pm
what filipe said is a procedural approach let's say sort(MyVector)... An OOP approach is MyVector.sort();


I think you got a very distorted idea of OOP. The difference between sort(MyVector) and MyVector.sort() is the syntax, not the semantics. Stuffing stuff into a class doesn't make the approach more object oriented at all.

Furthermore, yes you can specialize templates (templates are part of generic (http://en.wikipedia.org/wiki/Generic_programming ) programming, not object oriented programming (http://en.wikipedia.org/wiki/Object-oriented_programming ) by the way).

Anyways: If you want to have a new vector class using your type, but with a different interface possibly supporting more operations, the way to go would be this:

1
2
3
4
5
6
7
8
class MyTypeVector
{
private:
vector<MyType> MyObjects;
public:
//provide access to the normal vector operations, like the [] operator etc
//add your new methods
};


Always remember, aggregation>inheritance. Use aggregation when possible, inheritance when it's necessary (that doesn't mean to use aggregation when it's not necessary lol). If you didn't get it: You want to expand the interface. Inheritance however is only useful to provide new implementations of the same interface, and specialized templates are only useful when a certain generic implementation doesn't work with a specific type. So the only OO way to approach this is creating a new collection class that provides the interface you need/want.
Last edited on Mar 11, 2011 at 5:54pm
Mar 11, 2011 at 6:44pm
A few more notes:

First, if it's sort or any other very common algorithm, make sure that it is not already provided in the STL. A generic sort, for example, is provided.

Also, if it's just a logical separation of ideas that you're after, consider using a namespace. You could have a namespace that "contains" your algorithms while still implementing them as non-members. Remember that a class's interface can be more than just it's members. (Common examples of this are stream insertion and extraction operators.)
Mar 11, 2011 at 6:53pm
(Common examples of this are stream insertion and extraction operators.)

And the STL algorithms you mentioned earlier.
Mar 11, 2011 at 8:41pm
hanst99, thank you for your answer. You told to "provide access to the normal vector operations, like the [] operator etc". Maybe the question is stupid but, how can I do that ? It seems to me that I will do something like void resize(int x) { MyObjects.resize(x); } and so on for every public method from vector. Am I right? If YES, inheriting from vector<MyType> like I said in #0, I will only have to add my new methods. If I'm not, how can I do that writing less.

moorecm, thank you for suggestion, I'll consider using a namespace
Last edited on Mar 11, 2011 at 8:43pm
Mar 11, 2011 at 10:42pm
Yeah, you could do that. But I don't really like the idea of inheriting from a STL container.
Mar 11, 2011 at 11:45pm
But I don't really like the idea of inheriting from a STL container.

why? (besides the non-virtual destructor)
Mar 11, 2011 at 11:59pm

besides the non-virtual destructor


What? Destructors are never virtual.

It just feels wrong in this case. You don't really have any benefits from this speaking in an OO sense, you just end up writing a bit less code. Of course it's technically not wrong to say that MyTypeVector is a vector<MyType>, but I just don't think you should use inheritance like that just to save yourself writing a few trivial lines of code.
Last edited on Mar 12, 2011 at 12:03am
Mar 12, 2011 at 1:07am
closed account (D80DSL3A)
What? Destructors are never virtual.

Yes they can be. The need for them arises when a derived class object is allocated (with new) to a base class pointer:
baseObj* pB = new derivedObj;
When this object is deleted delete pB; ONLY the base class destructor will be called if the destructors are not virtual. This leaves bits and pieces of the derived object in memory (an incomplete destruction).
If the base objects destructor is virtual this problem is avoided. The derived objects destructor is called first, then the base object destructor is called so the derived object is properly deconstructed.

According to my text this is a problem which occurs only with dynamically allocated objects. Automatic objects will always be deconstructed properly.
Mar 12, 2011 at 1:18am
Funky. I thought they aren't cause you don't explicitly call them anyways.
Pages: 12