Linker Error: Abstract base and 2 derived classes in singleton pattern

V

Vinesh S

Hello all,

This is my first message to the group.

I have a question where i derive 2 child classes which are of
singleton pattern from an abstract base class.

Code:

//********************************************** test1.h
*******************************//
#include <iostream>
using namespace std;

class CPolygon {
protected:
int width, height;
public:
CPolygon(){};
virtual ~CPolygon(){};
void set_values (int a, int b)
{ width=a; height=b; }
virtual int area (void) = 0;
void printarea (void)
{ cout << this->area() << endl; }

};

class CRectangle: public CPolygon {
public:
int area (void)
{ return (width * height); }
static CRectangle* GetInstance()
{ if (!rectanglePtr) rectanglePtr = new CRectangle(); return
rectanglePtr; }
~CRectangle();
protected:
CRectangle();
static CRectangle* rectanglePtr;
CRectangle(CRectangle const&){};
CRectangle& operator=(CRectangle&){};
};

CRectangle* CRectangle::rectanglePtr = NULL;

class CTriangle: public CPolygon {
public:
int area (void)
{ return (width * height / 2); }

static CTriangle* GetInstance()
{ if (!trianglePtr) trianglePtr = new CTriangle(); return
trianglePtr; }
~CTriangle();
protected:
CTriangle();
static CTriangle* trianglePtr;
CTriangle(CTriangle const&){}
CTriangle& operator=(CTriangle&){};
};

CTriangle* CTriangle::trianglePtr = NULL;

//******************************************* test1.cpp
*******************//
#include "test1.h"

int main (void)
{
CPolygon *ppoly1 = CRectangle::GetInstance();
CTriangle *ppoly2 = CTriangle::GetInstance();
ppoly1->set_values (4,5);
ppoly2->set_values (4,5);
ppoly1->printarea();
ppoly2->printarea();
delete ppoly1;
delete ppoly2;
return 0;
}

so when i compile and link them

this is the error am looking at ....

[root@Krea-TV-DT1 IMGAdapter]# g++ -o test1.out test1.o
test1.o: In function `CRectangle::GetInstance()':
test1.cpp:
(.text._ZN10CRectangle11GetInstanceEv[CRectangle::GetInstance()]+0xa):
undefined reference to `CRectangle::rectanglePtr'
test1.cpp:
(.text._ZN10CRectangle11GetInstanceEv[CRectangle::GetInstance()]
+0x26): undefined reference to `CRectangle::CRectangle()'
test1.cpp:
(.text._ZN10CRectangle11GetInstanceEv[CRectangle::GetInstance()]
+0x47): undefined reference to `CRectangle::rectanglePtr'
test1.cpp:
(.text._ZN10CRectangle11GetInstanceEv[CRectangle::GetInstance()]
+0x4c): undefined reference to `CRectangle::rectanglePtr'
test1.o: In function `CTriangle::GetInstance()':
test1.cpp:
(.text._ZN9CTriangle11GetInstanceEv[CTriangle::GetInstance()]
+0xa): undefined reference to `CTriangle::trianglePtr'
test1.cpp:
(.text._ZN9CTriangle11GetInstanceEv[CTriangle::GetInstance()]
+0x26): undefined reference to `CTriangle::CTriangle()'
test1.cpp:
(.text._ZN9CTriangle11GetInstanceEv[CTriangle::GetInstance()]
+0x47): undefined reference to `CTriangle::trianglePtr'
test1.cpp:
(.text._ZN9CTriangle11GetInstanceEv[CTriangle::GetInstance()]
+0x4c): undefined reference to `CTriangle::trianglePtr'
collect2: ld returned 1 exit status

Please let me know as to what mistake am i doing .

Thanks,

Vinesh.S
 
R

red floyd

Hello all,

This is my first message to the group.

I have a question where i derive 2 child classes which are of
singleton pattern from an abstract base class.

Code:

General:
* Don't bother prefixing your classes with "C". That's an
MFC-ism and is generally unnecessary.
* void param lists are unnecessary. Use void f(), instead of
void f(void).

//********************************************** test1.h
*******************************//
#include<iostream>
using namespace std;

class CPolygon {
protected:
int width, height;
public:
CPolygon(){};
virtual ~CPolygon(){};
void set_values (int a, int b)
{ width=a; height=b; }
virtual int area (void) = 0;
void printarea (void)
{ cout<< this->area()<< endl; }

};

class CRectangle: public CPolygon {
public:
int area (void)
{ return (width * height); }
static CRectangle* GetInstance()
{ if (!rectanglePtr) rectanglePtr = new CRectangle(); return
rectanglePtr; }
~CRectangle();
protected:
CRectangle();
static CRectangle* rectanglePtr;
CRectangle(CRectangle const&){};
CRectangle& operator=(CRectangle&){};
};

Where are CRectangle() and ~CRectangle() defined?


This should probably not be in a header (though for this
toy example it works)
CRectangle* CRectangle::rectanglePtr = NULL;
class CTriangle: public CPolygon {
public:
int area (void)
{ return (width * height / 2); }

static CTriangle* GetInstance()
{ if (!trianglePtr) trianglePtr = new CTriangle(); return
trianglePtr; }
~CTriangle();
protected:
CTriangle();
static CTriangle* trianglePtr;
CTriangle(CTriangle const&){}
CTriangle& operator=(CTriangle&){};
};

This should probably not be in a header (though for this
toy example it works)
CTriangle* CTriangle::trianglePtr = NULL;

Similarly, where are CTriangle() and ~CTriangle()
defined()

//******************************************* test1.cpp
*******************//
#include "test1.h"

int main (void)
{
CPolygon *ppoly1 = CRectangle::GetInstance();
CTriangle *ppoly2 = CTriangle::GetInstance();
ppoly1->set_values (4,5);
ppoly2->set_values (4,5);
ppoly1->printarea();
ppoly2->printarea();
delete ppoly1;
delete ppoly2;
return 0;
}

I don't see what's wrong with the static members,
but you do have to declare those missing constructors
and destructors.
 
I

Ian Collins

Hello all,

This is my first message to the group.

I have a question where i derive 2 child classes which are of
singleton pattern from an abstract base class.

Code:

//********************************************** test1.h
*******************************//
#include<iostream>
using namespace std;

class CPolygon {

Why not just class Polygon? The 'C' is just noise.
protected:
int width, height;
public:
CPolygon(){};
virtual ~CPolygon(){};
void set_values (int a, int b)
{ width=a; height=b; }
virtual int area (void) = 0;

(void) is a Cism best not used in C++ code.
void printarea (void)
{ cout<< this->area()<< endl; }

};

class CRectangle: public CPolygon {
public:
int area (void)
{ return (width * height); }
static CRectangle* GetInstance()
{ if (!rectanglePtr) rectanglePtr = new CRectangle(); return
rectanglePtr; }
~CRectangle();

This isn't defined anywhere.
protected:
CRectangle();

This isn't defined anywhere.
static CRectangle* rectanglePtr;
CRectangle(CRectangle const&){};
CRectangle& operator=(CRectangle&){};

This shouldn't compile, missing return (also superfluous semi-colon).
};

CRectangle* CRectangle::rectanglePtr = NULL;

This shouldn't be in a header, static members must be defined once and
only once. Put the definition in a cpp file.
class CTriangle: public CPolygon {
public:
int area (void)
{ return (width * height / 2); }

static CTriangle* GetInstance()
{ if (!trianglePtr) trianglePtr = new CTriangle(); return
trianglePtr; }
~CTriangle();

This isn't defined anywhere.
protected:
CTriangle();

This isn't defined anywhere.
static CTriangle* trianglePtr;
CTriangle(CTriangle const&){}
CTriangle& operator=(CTriangle&){};

This shouldn't compile, missing return.
};

CTriangle* CTriangle::trianglePtr = NULL;

//******************************************* test1.cpp
*******************//
#include "test1.h"

int main (void)
{
CPolygon *ppoly1 = CRectangle::GetInstance();
CTriangle *ppoly2 = CTriangle::GetInstance();
ppoly1->set_values (4,5);
ppoly2->set_values (4,5);
ppoly1->printarea();
ppoly2->printarea();
delete ppoly1;
delete ppoly2;
return 0;
}
Please let me know as to what mistake am i doing .

Try the fixes I suggested and it should link.
 
P

Paul N

Hello all,

This is my first message to the group.

I have  a question where i derive 2 child classes which are of
singleton pattern from an abstract base class.

Others have answered this, but I thought I might make a general
comment. If you code that is not working, try cutting it down to
simpler stuff and see if that works. That can help narrow down the
problem, and also may give you a shorter piece of code to post if you
still need to. For instance, with your code, the problem wasn't that
you were deriving *two* classes; you could have tried deriving just
one and that would have given you a shorter piece of code to post.
Indeed, the problem wasn't with the deriving itself - I think you
would have had the same problem with a straightforward singleton.

But this is just a comment as to how to do things even beter - your
post was very good especially for a first post.

Hope this helps.
Paul.
 

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,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top