Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > vector of pure virtual base class

Reply
Thread Tools

vector of pure virtual base class

 
 
nw
Guest
Posts: n/a
 
      01-25-2007
Hi,

I have three classes, a template pure virtual base class, a template
derived class and a third which I would like to use to store copies of
the derived class. The code looks like this:

#include <iostream>
#include <vector>

using namespace std;

template <class _prec> class Base {
public:
_prec i;

Base() {
i = 12;
}

virtual void f() = 0;

};

template <class _prec> class Derived : public Base<_prec> {
public:
void f() {
std::cout << this->i << std::endl;
}
};

template <class _prec> class Collect {
public:
vector <Base<_prec> > vec;

Collect() {
}

void g(Base<_prec> &in) {
vec.push_back(in);
}
};

int main() {
Derived<int> d;
Collect<int> c;

c.g(d);

return 0;
}

This results in linking errors, which result from vector being unable
to create a copy of the pure virtual class. Can anyone suggest how I
should solve this?

My first attempted was to make the function in Base virtual, rather
than pure virtual (i.e. virtual void f() {}). This then compiles,
however when the object is extracted from the vector (i.e. I do
vec[0].f() in Collect), the base method is called not that of the
derived class. Any ideas?

I think this should all be standard C++ but I'm using gcc version 4.1.2
to compile this code.

Any help appreciated!

 
Reply With Quote
 
 
 
 
mlimber
Guest
Posts: n/a
 
      01-25-2007
On Jan 25, 2:39 pm, "nw" <n...@soton.ac.uk> wrote:
> I have three classes, a template pure virtual base class, a template
> derived class and a third which I would like to use to store copies of
> the derived class. The code looks like this:
>
> #include <iostream>
> #include <vector>
>
> using namespace std;
>
> template <class _prec> class Base {
> public:
> _prec i;
>
> Base() {
> i = 12;
> }
>
> virtual void f() = 0;
>
> };template <class _prec> class Derived : public Base<_prec> {
> public:
> void f() {
> std::cout << this->i << std::endl;
> }
>
> };template <class _prec> class Collect {
> public:
> vector <Base<_prec> > vec;
>
> Collect() {
> }
>
> void g(Base<_prec> &in) {
> vec.push_back(in);
> }
>
> };int main() {
> Derived<int> d;
> Collect<int> c;
>
> c.g(d);
>
> return 0;
>
> }This results in linking errors, which result from vector being unable
> to create a copy of the pure virtual class. Can anyone suggest how I
> should solve this?
>
> My first attempted was to make the function in Base virtual, rather
> than pure virtual (i.e. virtual void f() {}). This then compiles,
> however when the object is extracted from the vector (i.e. I do
> vec[0].f() in Collect), the base method is called not that of the
> derived class. Any ideas?
>
> I think this should all be standard C++ but I'm using gcc version 4.1.2
> to compile this code.
>
> Any help appreciated!


To operate on an object polymorphically, you need to either use a
pointer or a reference to access it. std::vectors on the other hand,
hold a copy of whatever object you put in them, so your vector either
needs to be of Base*, or probably better, std::tr1::shared_ptr<Base>
(aka boost::shared_ptr<Base>).

BTW, I'd guess you're getting compiler errors, not linker errors.

Cheers! --M

 
Reply With Quote
 
 
 
 
Alan Johnson
Guest
Posts: n/a
 
      01-25-2007


On Jan 25, 11:39 am, "nw" <n...@soton.ac.uk> wrote:
> Hi,
>
> I have three classes, a template pure virtual base class, a template
> derived class and a third which I would like to use to store copies of
> the derived class. The code looks like this:


> This results in linking errors, which result from vector being unable
> to create a copy of the pure virtual class. Can anyone suggest how I
> should solve this?


Templates are just obfuscating the core problem, which is that you are
trying to instantiate an abstract class, which just can't be done.
When you try to add to a vector of your abstract base type, you are
essentially doing the following:

class abstract_base
{
public:
virtual int f() = 0 ;
} ;

class concrete : public abstract_base
{
virtual int f() { return 42 ; }
} ;

int main()
{
concrete c ;
abstract_base ab(c) ; // Error, can't create an instance
// of an abstract class.
}


Even if your base class was not abstract, virtual methods only get
dynamically dispatched when called via pointers or references, so
storing a vector of your base class still wouldn't achieve what you
want.

The solution? Store a vector of pointers to your base class. Example:
std::vector<abstract_base *> v ;
concrete c ;
v.push_back(&c) ;

If you want the vector to "own" the objects to which it points, then
your easiest route will probably be to create the objects dynamically,
and keep a vector of boost::shared_ptr.

--
Alan Johnson

 
Reply With Quote
 
nw
Guest
Posts: n/a
 
      01-26-2007
> The solution? Store a vector of pointers to your base class. Example:
> std::vector<abstract_base *> v ;
> concrete c ;
> v.push_back(&c) ;
>
> If you want the vector to "own" the objects to which it points, then
> your easiest route will probably be to create the objects dynamically,
> and keep a vector of boost::shared_ptr.


Many thanks for your and mlimber's advice, I'll give it a go!

Thanks again!

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Pure virtual functions: declaring a function in a base class Martin C++ 5 08-26-2010 09:52 AM
Non-template class from a template base class with pure virtual methods vilarneto@gmail.com C++ 2 03-25-2007 08:19 PM
Abstract base class with pure virtual functions Arne Schmitz C++ 4 01-17-2007 06:16 PM
Can pure virtual function be called in base class constructor? PengYu.UT@gmail.com C++ 10 10-18-2005 03:45 PM
how to return different data types using a base class and pure virtual methods Mitch Mooney C++ 2 06-18-2004 07:52 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57