By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,915 Members | 1,280 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,915 IT Pros & Developers. It's quick & easy.

Pure virtual functions in Template class?

P: n/a
Is it possible to have pure virtual functions defined in a template
class? I'm trying to do something like this:

template <typename T>
class Singleton
{
public:
static T& getInstance(void)
{
if(m_pInstance == NULL)
m_pInstance = new T;

return *m_pInstance;
}

protected:
Singleton() { }
Singleton(const Singleton&);
virtual ~Singleton() { }
Singleton& operator=(const Singleton&);

private:
static T* m_pInstance;

};

template <typename T>
T* Singleton<T>::m_pInstance = NULL;

template <typename T>
class Resigtry
{
public:
...
virtual std::string getType() = 0;

protected:
...
virtual T* loadResource(std::fname) = 0;

};

class FontsRegistry
: public Registry<Font>
, public Singleton<FontsRegistry>
{
public:
std::string getType() { return "FONT!!"; }

protected:
Font* loadResource(std::fname) { return new Font(); }

friend class Singleton<FontsRegistry>;
};

but upon compilation i get:

C:\mingw\include\c++\3.4.2\bits\stl_list.h:: undefined reference to
`vtable for FontRegistry'
:C:\mingw\include\c++\3.4.2\bits\stl_list.h:: undefined reference to
`vtable for FontRegistry'
:: === Build finished: 2 errors, 2 warnings ===

I want to have a bunch of classes that handle external resources (i.e.
FontsRegistry for fonts, MeshRegistry for meshes, etc.) but to avoid
having to cut/paste code a whole bunch of times, I wanted to make an
abstract class Registry, that they can derive from.

Mar 24 '07 #1
Share this Question
Share on Google+
3 Replies


P: n/a
YellowMaple wrote:
Is it possible to have pure virtual functions defined in a template
class? I'm trying to do something like this:
.... non compilable code removed
>
but upon compilation i get:

C:\mingw\include\c++\3.4.2\bits\stl_list.h:: undefined reference to
`vtable for FontRegistry'
:C:\mingw\include\c++\3.4.2\bits\stl_list.h:: undefined reference to
`vtable for FontRegistry'
:: === Build finished: 2 errors, 2 warnings ===

I want to have a bunch of classes that handle external resources (i.e.
FontsRegistry for fonts, MeshRegistry for meshes, etc.) but to avoid
having to cut/paste code a whole bunch of times, I wanted to make an
abstract class Registry, that they can derive from.
The code below compiles and links - your problem is elsewhere. To make
it easier next time, try to make the code you post compile and
demonstrate the issue you observe.

#include <string>

template <typename T>
class Singleton
{
public:
static T& getInstance(void)
{
if(m_pInstance == NULL)
m_pInstance = new T;

return *m_pInstance;
}

protected:
Singleton() { }
Singleton(const Singleton&);
virtual ~Singleton() { }
Singleton& operator=(const Singleton&);

private:
static T* m_pInstance;

};

template <typename T>
T* Singleton<T>::m_pInstance = NULL;

template <typename T>
class Registry
{
public:
// ...
virtual std::string getType() = 0;

protected:
// ...
virtual T* loadResource(std::string) = 0;

};

class Font {};

class FontsRegistry
: public Registry<Font>
, public Singleton<FontsRegistry>
{
public:
std::string getType() { return "FONT!!"; }

protected:
Font* loadResource(std::string) { return new Font(); }

friend class Singleton<FontsRegistry>;
};

FontsRegistry x;

int main()
{
}
Mar 24 '07 #2

P: n/a
Sorry, for the sake of brevity I excluded most of the code. Here is
an accurate representation:

in Singleton.h:

#ifndef __SINGLETON_H
#define __SINGLETON_H

template <typename T>
class Singleton
{
public:
static T& getInstance(void)
{
if(m_pInstance == NULL)
m_pInstance = new T;

return *m_pInstance;
}

protected:
Singleton() { }
Singleton(const Singleton&);
virtual ~Singleton() { }
Singleton& operator=(const Singleton&);

private:
static T* m_pInstance;

};

template <typename T>
T* Singleton<T>::m_pInstance = NULL;

#endif

In Registry.h

#ifndef __REGISTRY_H
#define __REGISTRY_H

#include <map>
#include <string>
#include <algorithm>

#include <Design/Subject.h>
#include <Utility/Globals.h>
#include <Design/Singleton.h>

struct delete_ptr
{
template <typename T>
void operator() (const T& obj) const
{
delete obj.second;
}
};

template <typename ResourceType>
class Registry
: public Subject
{
public:
typedef std::string resource_type;

ResourceType* create(std::string);
void clear();
bool empty() { return m_list.empty(); }

virtual resource_type getType() = 0;

protected:
Registry() { }
virtual ~Registry() { clear(); }
Registry(const Registry&);
Registry& operator=(const Registry&);

virtual ResourceType* loadResource(std::string) = 0;

typedef std::map<resource_type, ResourceType*registry_list;
registry_list m_list;

};

template <typename ResourceType>
ResourceType* Registry<ResourceType>::create(std::string name)
{
return NULL;
}

template <typename ResourceType>
void Registry<ResourceType>::clear()
{
notifyAll();
for_each(m_list.begin(), m_list.end(), delete_ptr());
m_list.clear();
}

#endif

and finally, FontRegistry.h:

#ifndef __FONTREGISTRY_H
#define __FONTREGISTRY_H

#include <string>

#include <FTGLPixmapFont.h>

#include <Resources/Registry.h>

#define FONT_TYPE ".ttf"

class FontRegistry
: public Registry<FTFont>
, public Singleton<FontRegistry>
{
public:
~FontRegistry();

resource_type getType() { return FONT_TYPE; }

protected:
FTFont* loadResource(std::string) { return NULL; }

private:
FontRegistry() { }
FontRegistry(const FontRegistry&);
FontRegistry operator=(const FontRegistry&);

typedef FTGLPixmapFont FontType;

friend class Singleton<FontRegistry>;

};

#endif

The font registry is used like so:

FTFont* ftgl_font = FontRegistry::getInstance().create(font);

Compilation in Code::Blocks with the MinGW compiler gives these
errors:

C:\MinGW\bin\..\lib\gcc\mingw32\3.4.2\..\..\..\..\ include\c++
\3.4.2\backward\backward_warning.h:32: warning: #warning This file
includes at least one deprecated or antiquated header. Please consider
using one of the 32 headers found in section 17.4.1.2 of the C++
standard. Examples include substituting the <Xheader for the <X.h>
header for C++ includes, or <iostreaminstead of the deprecated
header <iostream.h>. To disable this warning use -Wno-deprecated.
...\..\Framework_01\src\System\Console.cc:44: warning: unused variable
'width'
C:\mingw\include\c++\3.4.2\bits\stl_list.h:: undefined reference to
`vtable for FontRegistry'
:C:\mingw\include\c++\3.4.2\bits\stl_list.h:: undefined reference to
`vtable for FontRegistry'
:: === Build finished: 2 errors, 2 warnings ===


Mar 24 '07 #3

P: n/a
YellowMaple wrote:
Sorry, for the sake of brevity I excluded most of the code. Here is
an accurate representation:
......
>
class FontRegistry
: public Registry<FTFont>
, public Singleton<FontRegistry>
{
public:
~FontRegistry();
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Your problem is here. This is a virtual destructor and you have not
implemented it.

Please take a few more minutes to make the code compilable (cut-n-paste)
so that the code you give shows the error without others having to guess
what are the other errors about.

This is the code I ended up with, I'm not sure it truly represents your
problem.

Another pointer, avoid #defines like the one you use for FONT_TYPE.

//in Singleton.h:

#include <string>

#ifndef __SINGLETON_H
#define __SINGLETON_H

template <typename T>
class Singleton
{
public:
static T& getInstance(void)
{
if(m_pInstance == NULL)
m_pInstance = new T;

return *m_pInstance;
}

protected:
Singleton() { }
Singleton(const Singleton&);
virtual ~Singleton() { }
Singleton& operator=(const Singleton&);

private:
static T* m_pInstance;

};

template <typename T>
T* Singleton<T>::m_pInstance = NULL;

#endif

//In Registry.h

#ifndef __REGISTRY_H
#define __REGISTRY_H

#include <map>
#include <string>
#include <algorithm>

//#include <Design/Subject.h>
//#include <Utility/Globals.h>
//#include <Design/Singleton.h>

struct delete_ptr
{
template <typename T>
void operator() (const T& obj) const
{
delete obj.second;
}
};

class Subject {};

template <typename ResourceType>
class Registry
: public Subject
{
public:
typedef std::string resource_type;

ResourceType* create(std::string);
void clear();
bool empty() { return m_list.empty(); }

virtual resource_type getType() = 0;

protected:
Registry() { }
virtual ~Registry() { clear(); }
Registry(const Registry&);
Registry& operator=(const Registry&);

virtual ResourceType* loadResource(std::string) = 0;

typedef std::map<resource_type, ResourceType*registry_list;
registry_list m_list;

};

template <typename ResourceType>
ResourceType* Registry<ResourceType>::create(std::string name)
{
return NULL;
}

template <typename ResourceType>
void Registry<ResourceType>::clear()
{
//notifyAll();
//for_each(m_list.begin(), m_list.end(), delete_ptr());
//m_list.clear();
}

#endif

//and finally, FontRegistry.h:

#ifndef __FONTREGISTRY_H
#define __FONTREGISTRY_H

#include <string>

//#include <FTGLPixmapFont.h>

//#include <Resources/Registry.h>

#define FONT_TYPE ".ttf"

class FTFont {};

class FontRegistry
: public Registry<FTFont>
, public Singleton<FontRegistry>
{
public:
~FontRegistry() {};

resource_type getType() { return FONT_TYPE; }

protected:
FTFont* loadResource(std::string) { return NULL; }

private:
FontRegistry() { }
FontRegistry(const FontRegistry&);
FontRegistry operator=(const FontRegistry&);

class FTGLPixmapFont {};

typedef FTGLPixmapFont FontType;

friend class Singleton<FontRegistry>;

};

#endif

int main()
{
FTFont* ftgl_font = FontRegistry::getInstance().create( "" );
}

Mar 24 '07 #4

This discussion thread is closed

Replies have been disabled for this discussion.