Re: Linker error : child class on singleton pattern derived from
abstract base class
Vinesh S wrote:
This is my first message to the group.
Welcome!
I have a question where i derive 2 child classes which are of
singleton pattern from an abstract base class.
So you have two singletons that have a common base class, if I understand
right.
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; }
};
Notes here:
- You don't need a trailing semicolon after every curly brace, there are
two superfluous ones.
- An explicit "void" parameter is a C-ism, it is implied in C++. The
preferred choice there is empty brackets for an empty parameter list.
class CRectangle: public CPolygon {
Danger! Keep in mind that public derivation is a IS-A relationship. You here
effectively claim that a polygon is a rectangle. The typical example where
such things go wrong is the relationship between circle and ellipse. You can
to some extent use either as base for the other, but neither fully fits as a
base for the other, because the inherent properties and behaviour of the
base are not extended but violated by the derived class.
static CRectangle* GetInstance()
{
if (!rectanglePtr)
rectanglePtr = new CRectangle();
return rectanglePtr;
}
Reformatted this one, the binary size and the execution speed don't increase
if you cram this onto a single line of code. Anyway, since this will never
return null, you could document that using a reference instead.
class CTriangle: public CPolygon {
Note: This gets even more obscure, you effectively claim a triangle is (a
polygon which is) a rectangle! Anyway, I'll simply assume that this is a
badly-chosen example and that the main point is that there is a baseclass, a
derived class and another that is further derived from the derived class.
I also see here that my initial assumption was wrong, you have a two-level
hierarchy where both derived classes provide the singleton pattern. This is
problematic, since if the most derived class CTriangle is instantiated, you
also create an instance of CPolygon and CRectangle. This conflicts with the
single instance of class CRectangle that seems to be guaranteed.
What I would suggest is that you separate the singleton issue from the
derivation or from the classes themselves. If they don't internally depend
on being singletons, leave them as non-singletons. If they do, then you also
can't derive from a class that can only be instantiated once. What you could
do is to share a single implementation, like e.g. both triangle and polygon
access the same implementation under the hood. The two classes could then be
non-singletons while the underlying implementation would be a singleton that
is shared by all instances.
#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
Two things here:
1. You should compile with warnings, these are often important.
2. You don't compile here but only link. You omitted the compile step.
test1.o: In function `CRectangle::GetInstance()':
test1.cpp:
(.text._ZN10CRectangle11GetInstanceEv[CRectangle::GetInstance()]+0xa):
undefined reference to `CRectangle::rectanglePtr'
This says that there is no definition of CRectangle::rectanglePtr. You
definitely define this in the code you have shown though, so I can only
assume that the code is not the code that you compiled and linked. Did you
perhaps put the line defining this into a separate file (which is the usual
approach), so you have the three files main.cpp, test1.h, test1.cpp? In that
case you forgot to link test1.o.
Also, a nasty question: Did you try removing CTriangle? If you deleted that
class and the places where it is used, and the problem persists, your
example was not minimal. Also, try removing the CRectangle baseclass.
Creating a minimal example is important for you to understand the problem!
In any case, I would first try to put the whole thing into a single source
file and remove things until I have a really minimal example.
Good luck!
Uli
--
Domino Laser GmbH
Gesch?ftsf?hrer: Thorsten F?cking, Amtsgericht Hamburg HR B62 932
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]