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