我需要具有应用程序生命周期的单例,保证创建/销毁和静态访问它。
#include <iostream>
#include <cstdlib>
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&); \
void operator=(const TypeName&)
#define M() C::sM()
#define M2() C::sM2()
using namespace std;
class C {
private:
static C* s;
~C() { cout << "~C()" << endl; }
static C* instance() {
if (s==NULL) { s=new C(); }
cout << "instance()=" << s << endl; return s;
}
static void cleanUp() { delete s; }
void m() { cout << "m()" << endl; }
void m2() { cout << "m2()" << endl; }
DISALLOW_COPY_AND_ASSIGN(C);
public:
C() {
cout << "C()" << endl; if (s==NULL) {
s=this; atexit(&cleanUp);
cout << "cleanUp is installed" << endl;
} else {
cout << "cleanUp is not installed" << endl;
}
}
void* operator new(size_t sz) {
void* p=NULL; if (s==NULL) { p=new char[sz]; } else { p=s; }
cout << "new(" << sz << ")=" << p << endl;
return p;
}
void operator delete(void* p, size_t sz) {
cout << "delete(" << sz << "," << p << ")" << endl;
if (p) delete[] static_cast<char*>(p); s=NULL;
}
void static sM() { cout << "sM()" << endl; instance()->m(); }
void static sM2() { cout << "sM2()" << endl; instance()->m2(); }
};
C* C::s = NULL;
int main() {
M();
M2();
C* p1 = new C();
C* p2 = new C();
}
但我不知道如何摆脱g ++警告:
test.cpp: In static member function 'static void C::operator delete(void*, size_t)':
test.cpp:22: warning: deleting 'void*' is undefined
如果我编写C *而不是void *,则析构函数开始在无限循环中调用自身。有人可以帮助我在没有警告的情况下获得干净的代码吗?当然是C ++ 98。
答案 0 :(得分:3)
我习惯写单身的方式(每当我真正需要的时候)是:
class Singleton
{
public:
static Singleton& instance()
{
static Singleton theInstance;
return theInstance;
}
private:
Singleton()
{
}
};
无需担心重载new
和delete
。
答案 1 :(得分:2)
您既不需要重载new()
也不需要delete()
。
而且您可能不需要向客户分发指针。参考将做。
单身人士的建造和破坏将在你的instance()
中完成,这可能是这样的:
static C& instance() {
static C _instance;
cout << "instance()" << endl;
return _instance;
}
这保证了构造和销毁,因为当第一个用户调用instance()
时,调用C的构造函数,并且仅在第一次调用时调用。
破坏将在您的计划结束时发生。
答案 2 :(得分:0)
要删除的类型为char*
:
void operator delete(void* p, size_t sz) {
cout << "delete(" << sz << "," << p << ")" << endl;
if (p) delete (char*) p;
}
您的新内容中存在错误:What's the difference between new char[10] and new char(10)
也许应该是:
p=new char[sz];
然后
delete[] (char*)p ;
----编辑:
删除纯粹主义者,牺牲了人们学习的清晰度; P:
delete[] static_cast<char*>(p) ;
(*实际上我很欣赏有关演员的说明)
答案 3 :(得分:0)
在我看来,如果您只删除new
和delete
重载(如果您想记录每个con / destruction,我没有真正看到它的重载),那么您的代码应该可以正常工作,在con / destructors中这样做,但下面应该修复你的错误。
由于您将char*
分配给p
,因此将其投放到删除中的char*
应该有效,即delete (char*)p;
。
但是,我相信p=new char(sz);
正在创建一个值为sz
的char,而不是一个大小为sz
的char数组。对于后者,您可能需要p=new char[sz];
,然后delete[] p
或delete[] (char*)p;
。