 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
tikviva Guest
|
Posted: Wed Jul 28, 2004 8:18 am Post subject: Singleton make error |
|
|
I am learning the Singleton design from the book "Design Pattern :
Element of resuable OO software". I've implmented the example from
book.
However, during the "make", the compiler beeps me with the following
error.
g++ -c singleton.cc
g++ -o main main.o singleton.o
singleton.o(.text+0x2a): In function `Singleton::Instance()':
: undefined reference to `Singleton::Singleton[in-charge]()'
collect2: ld returned 1 exit status
make: *** [main] Error 1
Here comes with the coding part...
/* Singleton.hh */
#ifndef __SINGLETON__
#define __SINGLETON__
#include <iostream>
using namespace std;
class Singleton {
public:
static Singleton* Instance();
protected:
Singleton();
private:
static Singleton* _instance;
};
#endif // __SINGLETON__
------------
/* Singleton.cc */
#include "singleton.hh"
using namespace std;
Singleton* Singleton::_instance = 0;
Singleton* Singleton::Instance() {
if (_instance == 0) {
_instance = new Singleton();
}
return _instance;
};
----------
// main.cc
#include "singleton.hh"
using namespace std;
int main()
{
Singleton *p1 = Singleton::Instance();
return 0;
}
----------
// Makefile
cpp = g++
main: main.o singleton.o
$(cpp) -o main main.o singleton.o
main.o: main.cc
$(cpp) -c main.cc
singleton.o: singleton.cc
$(cpp) -c singleton.cc
Can anyone please show me the correct way to fix this problem? Thank
you very much and I am really appreciate your help. =)
tikviva
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Alf P. Steinbach Guest
|
Posted: Wed Jul 28, 2004 12:37 pm Post subject: Re: Singleton make error |
|
|
* tikviva:
You forgot to define the default constructor.
When you declare it the compiler won't generate it for you.
Other comments:
| Quote: | /* Singleton.hh */
#ifndef __SINGLETON__
#define __SINGLETON__
#include <iostream
using namespace std;
|
Don't #include
Don't put 'using namespace std;' in any header file, because
it forces that on all client code that uses the header.
| Quote: | class Singleton {
public:
static Singleton* Instance();
|
This is Bad Design (TM).
You don't want client code to need to check for possible null-pointer.
To state in the language itself that this function always returns a
valid Singleton, change it to return a reference, like so:
static Singleton& Instance();
| Quote: | protected:
Singleton();
private:
static Singleton* _instance;
};
#endif // __SINGLETON__
|
OK.
| Quote: | ------------
/* Singleton.cc */
#include "singleton.hh"
using namespace std;
|
You don't need 'using namespace std;' here. Technically it doesn't
do any harm but not any good either. But it might cause problems
later to have irrelevant 'using namespace' clauses around.
| Quote: | Singleton* Singleton::_instance = 0;
Singleton* Singleton::Instance() {
if (_instance == 0) {
_instance = new Singleton();
}
return _instance;
};
|
Extra semicolon here should be removed.
This code assumes that it's OK that the Singleton is never destroyed.
To destroy it you can install an atexit-handler, or you can use the
local static variable idiom like so:
Singleton& Instance()
{
static Singleton theInstance;
return theInstance;
}
Here the overhead of checking for an existing instance (if any) is
moved to the language's runtime support and/or automatically generated
code, which can do it very efficiently and guaranteed without bugs.
| Quote: | ----------
// main.cc
#include "singleton.hh"
using namespace std;
int main()
{
Singleton *p1 = Singleton::Instance();
return 0;
|
Not necessary with explicit 'return' statement, but style-wise: I (but
not everybody) find it much more clear to use the symbolic constants
EXIT_SUCCESS and EXIT_FAILURE as return values for 'main'.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Jozef Saniga Guest
|
Posted: Wed Jul 28, 2004 12:38 pm Post subject: Re: Singleton make error |
|
|
Hi,
tikviva wrote:
| Quote: | g++ -c singleton.cc
g++ -o main main.o singleton.o
singleton.o(.text+0x2a): In function `Singleton::Instance()':
: undefined reference to `Singleton::Singleton[in-charge]()'
collect2: ld returned 1 exit status
make: *** [main] Error 1
Here comes with the coding part...
/* Singleton.hh */
#ifndef __SINGLETON__
#define __SINGLETON__
#include
using namespace std;
class Singleton {
public:
static Singleton* Instance();
protected:
Singleton();
|
I don't see Singleton::Singleton() defined anywhere. That's your problem.
| Quote: | private:
static Singleton* _instance;
};
#endif // __SINGLETON__
------------
/* Singleton.cc */
#include "singleton.hh"
using namespace std;
Singleton* Singleton::_instance = 0;
Singleton* Singleton::Instance() {
if (_instance == 0) {
_instance = new Singleton();
}
return _instance;
};
|
Jozef
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ryan Winter Guest
|
Posted: Wed Jul 28, 2004 12:44 pm Post subject: Re: Singleton make error |
|
|
tikviva wrote:
| Quote: | I am learning the Singleton design from the book "Design Pattern :
Element of resuable OO software". I've implmented the example from
book.
However, during the "make", the compiler beeps me with the following
error.
g++ -c singleton.cc
g++ -o main main.o singleton.o
singleton.o(.text+0x2a): In function `Singleton::Instance()':
: undefined reference to `Singleton::Singleton[in-charge]()'
collect2: ld returned 1 exit status
make: *** [main] Error 1
|
Your you've almost got your global variable, I mean singleton right. You are
receiving a link error as you have defined your own Constructor in the
header file, but not provided an implementation. See comments inline.
| Quote: | Here comes with the coding part...
/* Singleton.hh */
#ifndef __SINGLETON__
#define __SINGLETON__
#include
using namespace std;
|
This is evil. Never do this in a header file as it propogates through every
file that includes it. You dont actually need iostream anyway.
| Quote: | class Singleton {
public:
static Singleton* Instance();
protected:
Singleton();
private:
static Singleton* _instance;
};
#endif // __SINGLETON__
------------
/* Singleton.cc */
#include "singleton.hh"
using namespace std;
Singleton* Singleton::_instance = 0;
Singleton* Singleton::Instance() {
if (_instance == 0) {
_instance = new Singleton();
}
return _instance;
};
|
Insert this code here:
Singleton()
{
}
| Quote: | ----------
// main.cc
#include "singleton.hh"
using namespace std;
int main()
{
Singleton *p1 = Singleton::Instance();
return 0;
}
|
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ulrich Eckhardt Guest
|
Posted: Wed Jul 28, 2004 3:24 pm Post subject: Re: Singleton make error |
|
|
tikviva wrote:
| Quote: | #ifndef __SINGLETON__
#define __SINGLETON__
|
*BEEEP*
Wrong.
1. names with two underscores are reserved to the compiler, you must not use
them.
2. the name itself is so generic that it just calls for conflicts with other
include-guards.
| Quote: | #include
using namespace std;
|
I hope you know why this is bad in a header...
| Quote: | class Singleton {
[...]
Singleton();
};
|
You declared a dtor here.
| Quote: | /* Singleton.cc */
#include "singleton.hh"
using namespace std;
|
What, again? ;)
OK, here ends the file Sinlgeton.cc without the declared ctor being defined,
which is why you get the linker-errors.
Use CXX instead and don't set it in the makefile, i.e. like this:
main.o: main.cc
$(CXX) $(CXXFLAGS) -c main.cc
Uli
--
FAQ: http://parashift.com/c++-faq-lite/
/* bittersweet C++ */
default: break;
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Werner Salomon Guest
|
Posted: Wed Jul 28, 2004 4:07 pm Post subject: Re: Singleton make error |
|
|
[email]tikviva (AT) yahoo (DOT) com[/email] (tikviva) wrote in message news:<4b2febc7.0407272313.32dfc2b9 (AT) posting (DOT) google.com>...
| Quote: | I am learning the Singleton design from the book "Design Pattern :
Element of resuable OO software". I've implmented the example from
book.
However, during the "make", the compiler beeps me with the following
error.
g++ -c singleton.cc
g++ -o main main.o singleton.o
singleton.o(.text+0x2a): In function `Singleton::Instance()':
: undefined reference to `Singleton::Singleton[in-charge]()'
collect2: ld returned 1 exit status
make: *** [main] Error 1
Here comes with the coding part...
/* Singleton.hh */
#ifndef __SINGLETON__
#define __SINGLETON__
#include
using namespace std;
if You do this in a header-file, You switch the namespace-mechanismen |
off and can go into trouble.
Hint: If You want to use the 'using namespace ..' so do it only in a
cpp- (or cc-) file. If You come in trouble compiling this file You can
fix it in this file and it is not necessary to search all headers and
change many others.
| Quote: |
class Singleton {
public:
static Singleton* Instance();
protected:
Singleton();
private:
static Singleton* _instance;
};
#endif // __SINGLETON__
------------
/* Singleton.cc */
#include "singleton.hh"
using namespace std;
here You don't need 'using namespace std;' |
| Quote: | Singleton* Singleton::_instance = 0;
Singleton* Singleton::Instance() {
if (_instance == 0) {
_instance = new Singleton();
}
return _instance;
};
You forgot the implementation of the constructor |
Singleton::Singleton()
{}
... that's the reason for the 'undefined reference to
`Singleton::Singleton'
[...]
Greetings
Werner
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
tikviva Guest
|
Posted: Thu Jul 29, 2004 10:23 am Post subject: Re: Singleton make error |
|
|
Thank you very much for you guys help.
| Quote: | /* Singleton.hh */
#ifndef __SINGLETON__
#define __SINGLETON__
#include <iostream
using namespace std;
Don't #include
Don't put 'using namespace std;' in any header file, because
it forces that on all client code that uses the header.
|
Are you saying that , try not to include "using namespace std;" in all
the .hh files?
hmm .. it's my problem to have #include <iostream> in the coding, I am
so used to have this in my program, I am glad to change ;^)
| Quote: | class Singleton {
public:
static Singleton* Instance();
This is Bad Design (TM).
You don't want client code to need to check for possible null-pointer.
To state in the language itself that this function always returns a
valid Singleton, change it to return a reference, like so:
static Singleton& Instance();
|
This is cool , and not from the the book though, thanks =)
| Quote: | /* Singleton.cc */
#include "singleton.hh"
using namespace std;
You don't need 'using namespace std;' here. Technically it doesn't
do any harm but not any good either. But it might cause problems
later to have irrelevant 'using namespace' clauses around.
|
Rule: no "using namespace std;" in *.cc *.cpp *.c ???
| Quote: | Singleton* Singleton::_instance = 0;
Singleton* Singleton::Instance() {
if (_instance == 0) {
_instance = new Singleton();
}
return _instance;
};
Extra semicolon here should be removed.
This code assumes that it's OK that the Singleton is never destroyed.
To destroy it you can install an atexit-handler, or you can use the
local static variable idiom like so:
Singleton& Instance()
{
static Singleton theInstance;
return theInstance;
}
|
I don't quite understand this one, could you show me why is that ?
Will theInstance be destroyed after the function call?
| Quote: | Here the overhead of checking for an existing instance (if any) is
moved to the language's runtime support and/or automatically generated
code, which can do it very efficiently and guaranteed without bugs.
int main()
{
Singleton *p1 = Singleton::Instance();
return 0;
Not necessary with explicit 'return' statement, but style-wise: I (but
not everybody) find it much more clear to use the symbolic constants
EXIT_SUCCESS and EXIT_FAILURE as return values for 'main'.
}
|
like this? Add them after #inlcude "singleton.hh" ??
#define EXIT_SUCCESS true
#define EXIT_FAILURE false
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
tikviva Guest
|
Posted: Thu Jul 29, 2004 10:24 am Post subject: Re: Singleton make error |
|
|
| Quote: | #ifndef __SINGLETON__
#define __SINGLETON__
*BEEEP*
Wrong.
1. names with two underscores are reserved to the compiler, you must not use
them.
2. the name itself is so generic that it just calls for conflicts with other
include-guards.
|
For your coding style, what do you suggest? I just wanna learn a bit
more, and become a better programmer. =)
| Quote: | class Singleton {
[...]
Singleton();
};
You declared a dtor here.
|
no dot right , I got it =)
| Quote: | OK, here ends the file Sinlgeton.cc without the declared ctor being defined,
which is why you get the linker-errors.
cpp = g++
Use CXX instead and don't set it in the makefile, i.e. like this:
main.o: main.cc
$(CXX) $(CXXFLAGS) -c main.cc
Uli
|
you mean something like this?
CXX = g++
CXXFLAGS = .....
main.o: main.cc
$(CXX) $(CXXFLAGS) -c main.cc
Thank you so much Uli,
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Alf P. Steinbach Guest
|
Posted: Thu Jul 29, 2004 3:10 pm Post subject: Re: Singleton make error |
|
|
* tikviva:
| Quote: | Thank you very much for you guys help.
/* Singleton.hh */
#ifndef __SINGLETON__
#define __SINGLETON__
#include <iostream
using namespace std;
Don't #include
Don't put 'using namespace std;' in any header file, because
it forces that on all client code that uses the header.
Are you saying that , try not to include "using namespace std;" in all
the .hh files?
|
Ryan Winter, Ulrich Eckhardt and I are saying _don't_ put
'using namespace std;' in any header file.
| Quote: | hmm .. it's my problem to have #include <iostream> in the coding, I am
so used to have this in my program, I am glad to change ;^)
|
If the Singleton uses iostream's internally, #include <iostream> in the
implementation file.
But generally it's not a good idea to do i/o in a class whos principal
purpose isn't exactly that.
For that means the class can't be used with other i/o schemes, and it
means it can't be used in other context, and it introduces dependencies.
| Quote: |
/* Singleton.cc */
#include "singleton.hh"
using namespace std;
You don't need 'using namespace std;' here. Technically it doesn't
do any harm but not any good either. But it might cause problems
later to have irrelevant 'using namespace' clauses around.
Rule: no "using namespace std;" in *.cc *.cpp *.c ???
|
Unless you need it... ;-)
Some are fanatical about that, but it doesn't matter much in an
implementation file.
I think the "rule" here is: don't add things you don't need,
because they may cause trouble later on (even if just that you'll
be using some time trying to figure out why they're there).
| Quote: |
This code assumes that it's OK that the Singleton is never destroyed.
To destroy it you can install an atexit-handler, or you can use the
local static variable idiom like so:
Singleton& Instance()
{
static Singleton theInstance;
return theInstance;
}
I don't quite understand this one, could you show me why is that ?
Will theInstance be destroyed after the function call?
|
No, it will be created the first time the function is called, and
destroyed at program exit.
Static variables are destroyed in opposite order of creation.
The language does a lot for you, automatically.
| Quote: | Not necessary with explicit 'return' statement, but style-wise: I (but
not everybody) find it much more clear to use the symbolic constants
EXIT_SUCCESS and EXIT_FAILURE as return values for 'main'.
}
like this? Add them after #inlcude "singleton.hh" ??
#define EXIT_SUCCESS true
#define EXIT_FAILURE false
|
No, #include <cstddef> or whatever header it is that defines them.
If you use <iostream> then you already have these definitions.
Anyway, one reason to use those symbolic constants is that they're
_not_ defined as the values above.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Thu Jul 29, 2004 3:16 pm Post subject: Re: Singleton make error |
|
|
In article <4b2febc7.0407281850.656deae1 (AT) posting (DOT) google.com>, tikviva
<tikviva (AT) yahoo (DOT) com> writes
| Quote: | Are you saying that , try not to include "using namespace std;" in all
the .hh files?
hmm .. it's my problem to have #include <iostream> in the coding, I am
so used to have this in my program, I am glad to change ;^)
|
Certainly a using directive should never appear at file scope in a
header file, and for slightly different reasons a using declaration
shouldn't either. IMO the only reasonable general coding principle for
header files is that names should always be fully qualified, but any
exceptions should be encapsulated in a named (no header should include
an unnamed) namespace.
| Quote: |
class Singleton {
public:
static Singleton* Instance();
This is Bad Design (TM).
You don't want client code to need to check for possible null-pointer.
To state in the language itself that this function always returns a
valid Singleton, change it to return a reference, like so:
static Singleton& Instance();
This is cool , and not from the the book though, thanks =)
|
The C++ code in the book is well known to be well below production
quality and is only there to communicate ideas not as examples of code
to use in real programs.
| Quote: |
/* Singleton.cc */
#include "singleton.hh"
using namespace std;
You don't need 'using namespace std;' here. Technically it doesn't
do any harm but not any good either. But it might cause problems
later to have irrelevant 'using namespace' clauses around.
Rule: no "using namespace std;" in *.cc *.cpp *.c ???
|
The decision to use using directives in implementation files is the
choice of the programmer because such decisions will generally only
impact on the code in that file. In some circumstances I happily use
using directives, in others I will use using declarations and in yet
others I will use fully qualified names. And in yet others I use
namespace aliases.
Those choices are ones that should be made on an understanding of the
implications for each. When in doubt, use fully qualified names.
| Quote: |
Singleton* Singleton::_instance = 0;
Singleton* Singleton::Instance() {
if (_instance == 0) {
_instance = new Singleton();
}
return _instance;
};
Extra semicolon here should be removed.
This code assumes that it's OK that the Singleton is never destroyed.
To destroy it you can install an atexit-handler, or you can use the
local static variable idiom like so:
Singleton& Instance()
{
static Singleton theInstance;
return theInstance;
}
I don't quite understand this one, could you show me why is that ?
Will theInstance be destroyed after the function call?
|
No, static objects a persistent through the life of the program and are
only destroyed as part of the program termination code.
| Quote: |
Here the overhead of checking for an existing instance (if any) is
moved to the language's runtime support and/or automatically generated
code, which can do it very efficiently and guaranteed without bugs.
int main()
{
Singleton *p1 = Singleton::Instance();
return 0;
Not necessary with explicit 'return' statement, but style-wise: I (but
not everybody) find it much more clear to use the symbolic constants
EXIT_SUCCESS and EXIT_FAILURE as return values for 'main'.
}
like this? Add them after #inlcude "singleton.hh" ??
#define EXIT_SUCCESS true
#define EXIT_FAILURE false
|
NO! Not only should you never dream of doing such a thing, it would
actually result in bizarrely wrong program exits. To get the above you
should #include <cstdlib> and only use them for returns from main()
which is what they are for.
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|