怎样让一个类只能有一个实例?(200分)

  • 主题发起人 主题发起人 cAkk
  • 开始时间 开始时间
哦,不好意思,我也是瞎猜,那我试试吧。
 
BaKuBaKu 重载的类方法 NewInstance 很不错

顺便问一下cAKK, 为什么会有这种需求? 即在什么情况下需要一个类的所有对象共享一个实例?
 
要想使一个类只能有一个实例,在类里头做文章好象不太可能,因为生成的两个实例是相互
独立的。
 
基本就这样吧,谢谢BakuBaku.

这个问题的来源是这样的,最近和一个朋友谈论起OO,他问我如何用OO的方法实现
“一个程序只能运行一个实例”,我说我一般是用findwindow查找是否已经存在该
classname的窗口,他说这不是OO的方法,并且也不能在unix下面实现,然后他举了
一个C++的例子,和前面大家提供的差不多。于是我想用oBJECT pASCAL是否也能实现?

再次感谢.
 
btw: 用全局变量也不是一个好方法,也不是oo的方法。 :-)
 
BakuBaku的方法对于delphi而言是对的,
这其实正是delphi的有趣之处 -- 所有类其实都是指针。

C++的语法我都记不清了,如果没有static class myclass ...之类的语法,
那么C++中我认为是不可能实现这一目的的,如上面诸位所举的例子,请看下面代码:

class1 myobj1;
class1 myobj2;

这种静态对象的定义是C++中允许的(delphi中不存在),
谁能使这段代码编译出来的结果是只有一个实例?
 
温柔一刀,请试一下下面的类:

//------------------------------------------
//测试单类生成
//------------------------------------------

class OnlyOne
{
public:
static OnlyOne* install();
protected:
OnlyOne(){};
private:
static OnlyOne* One;
};

//--------------------------------
OnlyOne* OnlyOne::One=0;
//--------------------------------

OnlyOne* OnlyOne::install()
{
if(One==0){ One=new OnlyOne
};
return One;
};

对C++来讲,只要将构造函数放入保护或者私有部分,这时候系统就不会再允许在
堆栈或者数据段中生成类对象了。:)简单的重载new操作不行。
 
哦, 如果你说的和我理解的一致,并且都没错的话,
那么应该是可以的,这还是涉及Delphi与C++的区别,
delphi一切类都是tobject,protect constructor也没用。
另外,OnlyOne newOne;这样的语句有什么结果?
编译通不过还是其他?(没时间试验了)

顺便问一句,你是cAkk说的“一位朋友”吗? :-)
 

如下面使用:

void __fastcall TForm1::Button2Click(TObject *Sender)
{
//------------------------
OnlyOne one1;//错误!!
//------------------------
OnlyOne* One1=OnlyOne::install();
OnlyOne* One2=OnlyOne::install();
ShowMessage("One1="+IntToStr((int)One1)+','+
"One2="+IntToStr((int)One2));
}

系统提示如下:
[C++ Error]Main.cpp(30):E2247'OnlyOne::OnlyOne()'is not accessible;

就是说,系统在OnlyOne One1这样的语句地方,一方面构造一块内存空间,另一方面
调用构造函数,但是构造函数处于保护或私有状态,不允许外部调用,则在编译时出错。
就是说,我们可以通过控制构造函数或析构函数的属性,来控制一个类的实例的存储位
置,这些都是一些小技巧。

我不是cAKK说的"一位朋友" :-)
 
实际上,《Delphi从入门到精通》"第3章高级Object Pascal"
很明显的提示了一个方法。
正如BaKuBaKu所言。
 
后退
顶部