Inheriting from std::vector?

B

BCC

Hi,

A colleague has some code like this:

class CMyObject {
// Bunch of Member functions
}

class CMyObjectList: public std::vector<CMyObject>
{
// Bunch of member functions
}

I need to inherit the functionality of his object and list as well as add
some of my own:

class CMyPersonalObject: public CMyObject
{
// More stuff
}

class CMyPersonalObjectList: public CMyObjectList
{
// More stuff
}

But if I pass in CMyPersonalObjectList to a function, and then try to assign
the CMyPersonalObject to a local variable of that type, I get a compiler
error telling me that I cannot convert CMyObject to CMyPersonalObject... the
compiler thinks the list I passed in is made of the parent objects.

What is going on and how do I fix it?

Thanks,
B
 
L

lilburne

BCC said:
But if I pass in CMyPersonalObjectList to a function, and then try to assign
the CMyPersonalObject to a local variable of that type, I get a compiler
error telling me that I cannot convert CMyObject to CMyPersonalObject... the
compiler thinks the list I passed in is made of the parent objects.

What is going on and how do I fix it?

Would need to see the code where the assignment is made.
However, as std::vector doesn't have a virtual destructor it
shouldn't really be being used as a base class. That isn't
your actual problem though.
 
A

Alf P. Steinbach

A colleague has some code like this:

class CMyObject {
// Bunch of Member functions
}

Missing semicolon.


class CMyObjectList: public std::vector<CMyObject>
{
// Bunch of member functions
}

Ditto.

Without further information this inheritance is a little suspicious.

I can thing of good reasons to inherit from std::string, but not std::vector.



I need to inherit the functionality of his object and list as well as add
some of my own:

class CMyPersonalObject: public CMyObject
{
// More stuff
}

class CMyPersonalObjectList: public CMyObjectList
{
// More stuff
}

But if I pass in CMyPersonalObjectList to a function, and then try to assign
the CMyPersonalObject to a local variable of that type,

There is no relationship between CMyPersonalObjectList and CMyPersonalObject
in what you have shown, so the above seems meaningless.


I get a compiler
error telling me that I cannot convert CMyObject to CMyPersonalObject...

The compiler is right, you cannot do that unless you provide a conversion.


the compiler thinks the list I passed in is made of the parent objects.

Where on earth did you get that absurd idea? Compilers don't think.


What is going on

See e.g. <url: http://news.google.com/>.


and how do I fix it?

Perhaps follow the advice of Michael Moore?
 
G

Grzegorz Sakrejda

Hi,

A colleague has some code like this:

class CMyObject {
// Bunch of Member functions
}

class CMyObjectList: public std::vector<CMyObject>
{
// Bunch of member functions
}

I need to inherit the functionality of his object and list as well as add
some of my own:

class CMyPersonalObject: public CMyObject
{
// More stuff
}

class CMyPersonalObjectList: public CMyObjectList
{
// More stuff
}

But if I pass in CMyPersonalObjectList to a function, and then try to
assign
the CMyPersonalObject to a local variable of that type, I get a compiler
error telling me that I cannot convert CMyObject to CMyPersonalObject...
the
compiler thinks the list I passed in is made of the parent objects.

What is going on and how do I fix it?

Thanks,
B

std::vector is a template . CMyObjectList should also be a template, at
least if you want to have personalobject list.

template <class T> CObjectList : public std::vector<T> {
some more
};

typedef CObjectList<CMyPersonalObject> CMyPersonalObjectList;
 
D

Davlet Panech

BCC said:
Hi,

A colleague has some code like this:

class CMyObject {
// Bunch of Member functions
}

class CMyObjectList: public std::vector<CMyObject>
{
// Bunch of member functions
}

I need to inherit the functionality of his object and list as well as add
some of my own:

class CMyPersonalObject: public CMyObject
{
// More stuff
}

class CMyPersonalObjectList: public CMyObjectList
{
// More stuff
}

But if I pass in CMyPersonalObjectList to a function, and then try to assign
the CMyPersonalObject to a local variable of that type, I get a compiler
error telling me that I cannot convert CMyObject to CMyPersonalObject... the
compiler thinks the list I passed in is made of the parent objects.

It won't work, because the vector contains CMyObjects, not
CMyPersonalObjects. So whenever you insert a CMyPersonalObject in that
vector, it'll get "truncated" to it's base type. You might be able to use a
vector of pointers to (dynamically-allocated) CMyObjects (+derivatives)
instead, but you'll run into other problems:
- Manual memory allocation is difficult and error-prone (but "smart pointer"
libraries might help, see for example www.boost.org )
- You'll have to downcast the stored addresses all the time
- I think it is wrong to have CMyPersonalObjectList as a subclass of
CMyObjectList, because such hierarchy permits insertions of CMyObjects into
CMyPersonalObjectList (you might want to do a search on "Liskov Substitution
Principle" to learn why this is a bad idea. For example read this article:
http://www.brent.worden.org/articles/2000/liskovSubstitutionPrinciple.html).

What exactly are you trying to do? Maybe there's a better way to do it.
 
R

Rolf Magnus

lilburne said:
However, as std::vector doesn't have a virtual destructor it
shouldn't really be being used as a base class.

There is no problem with using it as a base class as long as you don't
destroy the object through a pointer to std::vector.
 
L

lilburne

Rolf said:
lilburne wrote:




There is no problem with using it as a base class as long as you don't
destroy the object through a pointer to std::vector.

And you ensure that how?
 
L

lilburne

Pete said:
You don't do it.

I take it you mean: you don't inherit from a class that
doesn't contain a virtual destructor, not that you don't
delete a pointer to a class that doesn't have a virtual
destructor.
 
P

Pete Becker

lilburne said:
I take it you mean: you don't inherit from a class that
doesn't contain a virtual destructor, not that you don't
delete a pointer to a class that doesn't have a virtual
destructor.

You take it wrong. Pay attention to context.
 
L

lilburne

Pete said:
You take it wrong. Pay attention to context.

Amazing:

#include <iostream>
#include <memory>

using namespace std;

class A {
public:
A();
~A();
};

class B : public A {
string s;
public:
B();
~B();
};

A::A() { cout << "A::A" << endl;}
A::~A() { cout << "A::~A" << endl;}
B::B() { cout << "B::B" << endl;}
B::~B() { cout << "B::~B" << endl;}

int main()
{
auto_ptr<A> a(new B);
return 0;
}
 
L

lilburne

Pete said:

Tsk! You jump in to sanction using a class inheritance
design, that not only restricts how the heirarchy may be
used, but which also has the potential to cause resource
leakage, and then become all sniffy.

Its no good simply saying 'don't do it', because it will be
done. If you took 10 'C++' programmers at random and asked
"What does the following program print?" you'd be lucky to
get the correct answer from 4 of them. Ask the 4 that got it
right the same question again having removed virtual from
A's destructor and you might get 2 left.

class A {
public:
virtual void func1() { cout << "a::func1" << endl; }
void func2() { cout << "a::func2" << endl; }
virtual void func3() { cout << "a::func3" << endl; }
virtual ~A() { cout << "a::~a" << endl; }
};

class B {
public:
virtual void func1() { cout << "b::func1" << endl; }
void func2() { cout << "b::func2" << endl; }
void func3() { cout << "b::func3" << endl; }
virtual ~B() { cout << "b::~b" << endl; }
};

int main()
{
B* b = new B;
A* a = b;
a->func1();
a->func2();
a->func3();

b->func1();
b->func2();
b->func3();

delete a;
return 0;
}

Its astonishing how many programmers do not understand the
import of the keyword virtual. But you know that.
 
A

Alf P. Steinbach

What was bad about it?

You're destroying a non-polymorphic class object polymorphically (through a
pointer to the base class object).

But you knew that.

It's illogical to ban usage of a feature just because that feature _can_
be abused, since almost all language features _can_ be abused, and I think
your use of such an illogical argument was the reason why Pete plonked you.
 
L

lilburne

Alf said:
You're destroying a non-polymorphic class object polymorphically (through a
pointer to the base class object).

But you knew that.

It's illogical to ban usage of a feature just because that feature _can_
be abused, since almost all language features _can_ be abused, and I think
your use of such an illogical argument was the reason why Pete plonked you.

It is unlikely that Pete Becker would derive a class from
a base that has a non-virtual destructure, without some
overriding reason to do so. Because he knows it is a
resource leak waiting to happen, and that safer alternatives
are usually available.

To pretend that you can ensure that the polymorphic deletion
on such a class heirarchy can be avoid just by saying "Don't
do it" is ridiculous. The OP not only has an inheritance
tree of depth four, but is also inheriting from a class that
already exists. As there are already functions in the system
that process the base class polymorphism is going to occur.

Certain language features ought to be used with caution, IMO
one should learn how to use them properly before you start
to abuse them.
 
A

Alf P. Steinbach

Certain language features ought to be used with caution, IMO
one should learn how to use them properly before you start
to abuse them.

Well, modest that I am I find it unlikely that either Pete or I don't
know how to use inheritance properly, and I find it unlikely that either
of us would abuse the mechanism.

Perhaps you're referring to the OP?

But the OP didn't code inheritance from std::vector; he's, er, inherited
that code...

Perhaps, then, you're referring to your own abusive example code?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,024
Latest member
ARDU_PROgrammER

Latest Threads

Top