473,387 Members | 1,520 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Pure virtual functions in Template class?

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
3 3285
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
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
by: cppaddict | last post by:
Hi, I know that it is illegal in C++ to have a static pure virtual method, but it seems something like this would be useful when the following 2 conditions hold: 1. You know that every one...
5
by: Steven T. Hatton | last post by:
This is a question about coding styles. I've seen some cases where the programmer has redeclared the pure virtual functions from an interface class in the implementation derived from it. For...
11
by: santosh | last post by:
Hello, I was going through the Marshal Cline's C++ FAQ-Lite. I have a doubt regarding section 33.10. Here he is declaring a pure virtual destructor in the base class. And again defining...
6
by: Dilip | last post by:
Hi All I have a pure virtual function in my base class that my derived instances override. What are the likely causes for VC++ 7.1 to complain of unresolved external symbol on that pure virtual...
3
by: Dmitry Prokoptsev | last post by:
Hello, I need to write a class for exceptions which can be thrown, caught, stored and thrown once again. I have written the following code: --- begin --- #include <string> class Exception...
6
by: Miguel Guedes | last post by:
Hello, I recently read an interview with Bjarne Stroustrup in which he says that pure abstract classes should *not* contain any data. However, I have found that at times situations are when it...
11
by: mathieu | last post by:
Hi there, I don't think I'll be able to describe my issue correctly, so instead I'll just give a pseudo C++ code I am struggling with. Basically I am looking for a 'pure virtual template'...
13
by: Mike -- Email Ignored | last post by:
Is a pure virtual function in allowed in a template base class? In any case, I have one working. Am I skating on thin ice? Thanks, Mike.
7
by: Tonni Tielens | last post by:
I'm trying to create a pure virtual class describing an interface. Normally, when I do this I make the destructor pure virtual so that, even if there are no members in the class, it cannot be...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.