求助啊,怎么实现一个C++的singleton啊?

时间:2022-09-09 08:44:36
偶是先学的C#再看的C++,C++有很多东东弄得我晕了
class ID3V2TagParser {
private:
static ID3V2TagParser* aninstance; QMap<ID3V2_VERSION_NAME,ID3V2Version*> tagVersion;
QMap<ID3V2_VERSION_NAME,QMap<ID3V2_FRAME_NAME,ID3V2FrameParser*> > frames;
 ID3V2TagParser();
public:

static ID3V2TagParser* CreateInstance() 
{
if (NULL==aninstance)
aninstance=new ID3V2TagParser();
return  aninstance;
}

virtual ~ID3V2TagParser();
ID3V2File* LoadFile(QString path);
void SaveFile(ID3V2File* file);
void RegisterVersion(ID3V2Version* v);
void RegisterFrameParser(ID3V2FrameParser* fp);
};
上面的链接时出错,错误 1 error LNK2001: 无法解析的外部符号 "private: static class Aquarius::ID3::ID3V2TagParser * Aquarius::ID3::ID3V2TagParser::aninstance" (?aninstance@ID3V2TagParser@ID3@Aquarius@@0PAV123@A) main.obj AID3C
为啥?

9 个解决方案

#1


static ID3V2TagParser* CreateInstance() 
{
static ID3V2TagParser* aninstance; if (NULL==aninstance)
aninstance=new ID3V2TagParser();
return  aninstance;
}
搞定了啊,把static ID3V2TagParser* aninstance放到CreateInstance() 
函数里面就好了。

#2


在类外初始外static变量应该也可以
将这个写在类外
ID3V2TagParser* ID3V2TagParser::aninstance=NULL;

#3


写在类外面不是到处都可以访问了啊,咋封装啊

#4


2楼的意思应该是static成员在类外初始化
可以通过对象和实例调用

#5


引用 3 楼 lishuai369 的回复:
写在类外面不是到处都可以访问了啊,咋封装啊

不是啊。 
你不是有::吗

#6


手头刚好有个
#include <iostream>
using namespace std;

class Singleton
{
public:
static Singleton* getInstance();
static void removeInstance();

private:
static Singleton*  m_Instance;
Singleton(){}
Singleton(const Singleton& rValue){}
Singleton& operator =(const Singleton& rValue){}
};

Singleton* Singleton::m_Instance = NULL;

Singleton* Singleton::getInstance()
{
if (m_Instance)
{
return m_Instance;
}
m_Instance = new Singleton;
return m_Instance;
}

void Singleton::removeInstance()
{
if (m_Instance)
{
delete m_Instance;
m_Instance = NULL;
}
}
这个是普通的写法,等下给你个template的

#7


#include <iostream>
#include <cassert>

using namespace std;

template<typename T>
class SingletonTemplateBase
{
private:
static T* sm_instance;
protected:
SingletonTemplateBase()
{
assert(sm_instance == NULL);
sm_instance = static_cast<T*>(this);
}
virtual ~SingletonTemplateBase()
{
assert(sm_instance != NULL);
sm_instance = 0;
}

public:
static void RemoveInstance()
{
assert(sm_instance);
if(sm_instance)
{
delete sm_instance;
}
assert(sm_instance == NULL);
}

static T* getInstancePtr()
{
if(sm_instance == NULL)
sm_instance = new T();
return sm_instance;
}

static T& getInstanceRef()
{
return *sm_instance;
}
};

template<typename T>
T* SingletonTemplateBase<T>::sm_instance = NULL;

class testClass :public SingletonTemplateBase<testClass>
{
public:
int getAge(){return age;}
void setAge(int age){this->age = age;}
private:
int age;
};

int main()
{
testClass::getInstancePtr()->setAge(100);
cout<<testClass::getInstancePtr()->getAge();

testClass::RemoveInstance();
system("pause");
return 0;
}
这个是个模板的,注意singleton的内存泄漏问题,也就是static instance问题,程序退出之前一定要调用
testclass::removeInstance
另外值得注意的就是这个singleton比较简陋,没有多线程保护,普通用下可以,如果要功能比较全面的Singleton推荐你看看loki里面的Singleton,那个Singleton是我见过的Singleton最全面的~

#8


C++和java C#的差距还是比较大的,我还不适应啊。老是把java的思维来考虑C++,有没有一本比较好的C++的设计模式的书啊,推荐一下看看。

#9


引用 8 楼 lishuai369 的回复:
C++和java C#的差距还是比较大的,我还不适应啊。老是把java的思维来考虑C++,有没有一本比较好的C++的设计模式的书啊,推荐一下看看。

记得gof设计模式里面就是用c++和smalltalk描述了部分例子的。
记得一定要把第一章好好读读。

C++中涉及设计模式的有:modern c++ design。
但是这并不适合你看,不过可以看看里面讲单件那章,可能遇到的问题。
单件很简单,但是实现起来很复杂。
如果需求简单:
class A
{
public:
A& Instance()
{
 static A __a;
 return __a;
}
private:
A(){}
...
};
能满足好些场景的需要了。

#1


static ID3V2TagParser* CreateInstance() 
{
static ID3V2TagParser* aninstance; if (NULL==aninstance)
aninstance=new ID3V2TagParser();
return  aninstance;
}
搞定了啊,把static ID3V2TagParser* aninstance放到CreateInstance() 
函数里面就好了。

#2


在类外初始外static变量应该也可以
将这个写在类外
ID3V2TagParser* ID3V2TagParser::aninstance=NULL;

#3


写在类外面不是到处都可以访问了啊,咋封装啊

#4


2楼的意思应该是static成员在类外初始化
可以通过对象和实例调用

#5


引用 3 楼 lishuai369 的回复:
写在类外面不是到处都可以访问了啊,咋封装啊

不是啊。 
你不是有::吗

#6


手头刚好有个
#include <iostream>
using namespace std;

class Singleton
{
public:
static Singleton* getInstance();
static void removeInstance();

private:
static Singleton*  m_Instance;
Singleton(){}
Singleton(const Singleton& rValue){}
Singleton& operator =(const Singleton& rValue){}
};

Singleton* Singleton::m_Instance = NULL;

Singleton* Singleton::getInstance()
{
if (m_Instance)
{
return m_Instance;
}
m_Instance = new Singleton;
return m_Instance;
}

void Singleton::removeInstance()
{
if (m_Instance)
{
delete m_Instance;
m_Instance = NULL;
}
}
这个是普通的写法,等下给你个template的

#7


#include <iostream>
#include <cassert>

using namespace std;

template<typename T>
class SingletonTemplateBase
{
private:
static T* sm_instance;
protected:
SingletonTemplateBase()
{
assert(sm_instance == NULL);
sm_instance = static_cast<T*>(this);
}
virtual ~SingletonTemplateBase()
{
assert(sm_instance != NULL);
sm_instance = 0;
}

public:
static void RemoveInstance()
{
assert(sm_instance);
if(sm_instance)
{
delete sm_instance;
}
assert(sm_instance == NULL);
}

static T* getInstancePtr()
{
if(sm_instance == NULL)
sm_instance = new T();
return sm_instance;
}

static T& getInstanceRef()
{
return *sm_instance;
}
};

template<typename T>
T* SingletonTemplateBase<T>::sm_instance = NULL;

class testClass :public SingletonTemplateBase<testClass>
{
public:
int getAge(){return age;}
void setAge(int age){this->age = age;}
private:
int age;
};

int main()
{
testClass::getInstancePtr()->setAge(100);
cout<<testClass::getInstancePtr()->getAge();

testClass::RemoveInstance();
system("pause");
return 0;
}
这个是个模板的,注意singleton的内存泄漏问题,也就是static instance问题,程序退出之前一定要调用
testclass::removeInstance
另外值得注意的就是这个singleton比较简陋,没有多线程保护,普通用下可以,如果要功能比较全面的Singleton推荐你看看loki里面的Singleton,那个Singleton是我见过的Singleton最全面的~

#8


C++和java C#的差距还是比较大的,我还不适应啊。老是把java的思维来考虑C++,有没有一本比较好的C++的设计模式的书啊,推荐一下看看。

#9


引用 8 楼 lishuai369 的回复:
C++和java C#的差距还是比较大的,我还不适应啊。老是把java的思维来考虑C++,有没有一本比较好的C++的设计模式的书啊,推荐一下看看。

记得gof设计模式里面就是用c++和smalltalk描述了部分例子的。
记得一定要把第一章好好读读。

C++中涉及设计模式的有:modern c++ design。
但是这并不适合你看,不过可以看看里面讲单件那章,可能遇到的问题。
单件很简单,但是实现起来很复杂。
如果需求简单:
class A
{
public:
A& Instance()
{
 static A __a;
 return __a;
}
private:
A(){}
...
};
能满足好些场景的需要了。