Forward declaration and typedefs

S

Simon Elliott

For some time I've been using typedefs for STL containers for reasons
outlined in:

http://www.gotw.ca/gotw/046.htm

However a major downside to this is that you can't forward declare a
typedef of a STL container:

#include <vector>
struct foo
{
int f1;
};
typedef std::vector<foo> fooVector;
// Can't forward declare fooVector

However, by deriving a class from the container, it becomes possible to
forward declare it:

class fooVector:public std::vector<foo>{};

This appears to allow me to treat fooVector as a std::vector<foo> and
to forward declare it:

class fooVector; // OK

In general it's not recommended to inherit from STL containers because
they don't have virtual destructors. Am I correct in thinking that the
above usage is safe because I'm not dealing with the fooVector class
polymorphically?

Is there any way to improve on the above so that other developers don't
inadvertantly use fooVector in a dangerous manner?
 
G

Gianni Mariani

Simon Elliott wrote:
...
In general it's not recommended to inherit from STL containers because
they don't have virtual destructors.

Nonsense. It's perfectly safe to inherit from objects that don't have
virtual destructors.

Am I correct in thinking that the
above usage is safe because I'm not dealing with the fooVector class
polymorphically?

see above.
Is there any way to improve on the above so that other developers don't
inadvertantly use fooVector in a dangerous manner?

Get better developers.
 
H

Howard

Simon Elliott said:
For some time I've been using typedefs for STL containers for reasons
outlined in:

http://www.gotw.ca/gotw/046.htm

However a major downside to this is that you can't forward declare a
typedef of a STL container:

#include <vector>
struct foo
{
int f1;
};
typedef std::vector<foo> fooVector;
// Can't forward declare fooVector

However, by deriving a class from the container, it becomes possible to
forward declare it:

class fooVector:public std::vector<foo>{};

This appears to allow me to treat fooVector as a std::vector<foo> and
to forward declare it:

class fooVector; // OK

In general it's not recommended to inherit from STL containers because
they don't have virtual destructors. Am I correct in thinking that the
above usage is safe because I'm not dealing with the fooVector class
polymorphically?

Is there any way to improve on the above so that other developers don't
inadvertantly use fooVector in a dangerous manner?

I'm not sure why you would want to forward declare that in the first
place...? A forward declaration is needed when you have a dependency on an
external class (or between classes in the same header), such as having a
pointer to another class inside your class. But if you're including the
<vector> header in your header, and you've successfully typedef'd it there,
what's to prevent you from including in instance of (or pointer to) that new
type it in your class? Why do you need to forward declare it? Like this:

// .h file
#ifndef MYVEC_H
#define MYVEC_H

#include <vector>

typedef std::vector<int>MyVector;

class VectorHolder
{
MyVector m_vector;
};

#endif
// end .h file

That works for me. What problem are you having that requires a forward
declaration?

-Howard



-Howard
 
H

Howard

pointer to another class inside your class. But if you're including the
<vector> header in your header, and you've successfully typedef'd it
there, what's to prevent you from including in instance of (or pointer to)
that new type it in your class? Why do you need to forward declare it?
Like this:

Should read:
 
S

Simon Elliott

// .h file
#ifndef MYVEC_H
#define MYVEC_H

#include <vector>

typedef std::vector<int>MyVector;

class VectorHolder
{
MyVector m_vector;
};

#endif
// end .h file

Let's call this header myvec.hpp.
That works for me. What problem are you having that requires a
forward declaration?

Two reasons:

1/ Elimination of headers. Suppose I want to have a pointer or
reference to MyVector in another header, but I don't want to include
myvec.hpp in that header. This reduces compile time dependencies and is
considered a Good Thing.

2/ Circular references. The classic example is when you have two
classes which need to contain a pointer to each other:

class bar; // Need this forward declaration to get this to compile

class foo
{
bar* bar_ptr_;
};

class bar
{
foo* foo_ptr_;
};
 
S

Simon Elliott

Nonsense. It's perfectly safe to inherit from objects that don't
have virtual destructors.

It's only safe if you can be sure that no-one is going to try to use
the objects polymorphically.
 

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

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,007
Latest member
obedient dusk

Latest Threads

Top