LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 05-12-2008, 04:04 PM   #1
x_terminat_or_3
Member
 
Registered: Mar 2007
Location: Plymouth, UK
Distribution: Fedora Core, RHEL, Arch
Posts: 342

Rep: Reputation: 38
C++ Trying singleton behavior, keep getting 'undefined reference to Class::instance()


Hi there,

I'm trying to get my head around C++ programming and would appreciate some help here.

First, I'm trying to abstract database access by making a database class.

I want singleton behavior, but it keeps telling me

'undefined reference to `Database::getInstance()' ' even though I made it public static.

Where did I go wrong?

Code:
main.cpp

#include "src/Database.h"

int main() {

	const Database* db=Database::getInstance();
}
Code:
Database.h

class Database {

	protected: 
		static Database* _instance;

	public:
		static Database* getInstance();

	protected:

		Database();
};
Code:
Database.cpp
#include "/usr/include/mysql/mysql.h"
#include <stdio.h>
#include "Database.h"


Database* Database::getInstance() {

	Database* out=Database::_instance;
		
	if(!(out)) {

		out=new Database();
	}
			
	return out;
}


Database::Database() {

	int blabla=0;
}
Any help is appreciated. Thanks
 
Old 05-12-2008, 05:06 PM   #2
R00ts
Member
 
Registered: Mar 2004
Location: Austin TX, USA
Distribution: Ubuntu 11.10, Fedora 16
Posts: 547

Rep: Reputation: 30
You need to initialize your static member in your .cpp file. Do this near the top of the file:

Code:
Database::_instance = NULL;
 
Old 05-12-2008, 05:31 PM   #3
x_terminat_or_3
Member
 
Registered: Mar 2007
Location: Plymouth, UK
Distribution: Fedora Core, RHEL, Arch
Posts: 342

Original Poster
Rep: Reputation: 38
I've changed it to this:

Code:
Database.cpp
#include "/usr/include/mysql/mysql.h"
#include <stdio.h>
#include "Database.h"

Database* Database::_instance = NULL;

Database* Database::getInstance() {

	Database* out=Database::_instance;
		
	if(!(out)) {

		out=new Database();
	}
			
	return out;
}


Database::Database() {

	int blabla=0;
}
But it still throws the same error:

Quote:
main.cpp:5: undefined reference to `Database::getInstance()'
 
Old 05-12-2008, 05:40 PM   #4
BrianK
Senior Member
 
Registered: Mar 2002
Location: Los Angeles, CA
Distribution: Debian, Ubuntu
Posts: 1,334

Rep: Reputation: 51
how are you compiling it? Are you linking Database.o?

to save back & forth time, you should be doing something like:

g++ -c Database.cpp <-- this will make Database.o
g++ -o main Database.o main.cpp <-- this will make an executable called main

Last edited by BrianK; 05-12-2008 at 05:42 PM.
 
Old 05-12-2008, 05:48 PM   #5
x_terminat_or_3
Member
 
Registered: Mar 2007
Location: Plymouth, UK
Distribution: Fedora Core, RHEL, Arch
Posts: 342

Original Poster
Rep: Reputation: 38
That did the trick. Thanks

I was using kdevelop with the automake tools, obviously did something wrong there then.

Thanks for your help.
 
Old 05-12-2008, 10:41 PM   #6
tuxdev
Senior Member
 
Registered: Jul 2005
Distribution: Slackware
Posts: 2,012

Rep: Reputation: 115Reputation: 115
That's not a singleton. A standard singleton pattern uses function-local statics like:
Code:
class Database {

	public:
		static Database &get();

	protected:

		Database();
};
and
Code:
Database &Database::get() {
	static Database db;	
	return db;
}
Now, this isn't the only good pattern for this, but it's the safest one that I can use without going through somersaults. For example, if you need to have multiple implementations of a Database interface, you'll need to handle the singleton in a much more complicated fashion. I using the smaller method name to acquire the instance because that part really isn't important, but what you do with it. I give more space for the important stuff and less space for stuff I don't really care about.
 
Old 05-13-2008, 06:29 AM   #7
dmail
Member
 
Registered: Oct 2005
Posts: 970

Rep: Reputation: Disabled
Quote:
Originally Posted by tuxdev View Post
That's not a singleton.
I will come back to this.
Quote:
A standard singleton pattern uses function-local statics like:
Who says? It is a singleton if it allows only one instance which is made global, which is the definition of a singleton.


Now can you see any problems with your class? It is possible to create more than one instance see the below code snippet.
Code:
int main() {

	const Database* db=Database::getInstance();
        Database foo(*db);
        assert(&foo == db);
}
For a generic Singleton template see http://www.liamdevine.co.uk/code/singleton.php

Last edited by dmail; 05-13-2008 at 06:37 AM.
 
Old 05-13-2008, 09:56 AM   #8
tuxdev
Senior Member
 
Registered: Jul 2005
Distribution: Slackware
Posts: 2,012

Rep: Reputation: 115Reputation: 115
Quote:
Who says? It is a singleton if it allows only one instance which is made global, which is the definition of a singleton.
Scott Meyers, he's the guy who thought that version up and made it famous. I never said it was the only way, either.

Quote:
Now can you see any problems with your class? It is possible to create more than one instance see the below code snippet.
Sorry, I neglected to put the copy constructor in the in the right place. You didn't have to blow the mistake out of proportion, though.
Code:
class Database {

	public:
		static Database &get();

	protected:

		Database();
		Database(const Database &);
};
 
Old 05-13-2008, 10:16 AM   #9
dmail
Member
 
Registered: Oct 2005
Posts: 970

Rep: Reputation: Disabled
Quote:
Sorry, I neglected to put the copy constructor in the in the right place. You didn't have to blow the mistake out of proportion, though.
Sorry you have misinterpreted that it was intended for the OP, I realise your code was just an example.
 
Old 05-13-2008, 12:56 PM   #10
x_terminat_or_3
Member
 
Registered: Mar 2007
Location: Plymouth, UK
Distribution: Fedora Core, RHEL, Arch
Posts: 342

Original Poster
Rep: Reputation: 38
Thanks all, to wrap it up, could you guys tell me what exactly the difference is between Database* and Database& both are references no?
 
Old 05-13-2008, 02:01 PM   #11
tuxdev
Senior Member
 
Registered: Jul 2005
Distribution: Slackware
Posts: 2,012

Rep: Reputation: 115Reputation: 115
Quote:
Thanks all, to wrap it up, could you guys tell me what exactly the difference is between Database* and Database& both are references no?
Database * is a pointer, which you might end up deleting somehow. It's much harder to delete a reference like Database &. Also, you are communicating to the programmer using this singleton that the instance returned is never null, since references can never be null (actually, they can, but that's another long obtuse discussion about C++ and compiler implementations). Some singletons need construction parameters, so in that case the singleton acquisition would return a pointer since it should return null if the proper initialization hasn't happened yet.

Quote:
Sorry you have misinterpreted that it was intended for the OP, I realise your code was just an example.
Okay, we're cool then ;-). The original code actually has a more fundamental problem than copy construction. getInstance never changes _instance, so each call to it makes a new object.

@xterm: It's a generally bad idea to use names that start with _, it's possible that those are reserved by the compiler (there's complicated rules as to what exactly is and is not reserved and it's easier to avoid the situation)

Last edited by tuxdev; 05-13-2008 at 02:08 PM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
undefined reference to.... crapodino Programming 1 01-13-2008 07:05 PM
Singleton delete instance Genar Programming 1 03-04-2007 09:34 AM
Undefined reference to: ashlesha Programming 5 11-08-2006 01:07 PM
"undefined reference" to a template class function btb Programming 3 08-25-2005 05:02 PM
Instance of a class? mikeshn Programming 3 06-03-2002 10:38 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 06:48 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration