如何实现一个enumeration类(内详)?

lifanxi 2003-08-11 10:25:32
看Thinking in Java时看到下面这样一段程序:
//: c07:music:Note.java
// Notes to play on musical instruments.
package c07.music;
import com.bruceeckel.simpletest.*;

public class Note {
private String noteName;
private Note(String noteName) {
this.noteName = noteName;
}
public String toString() { return noteName; }
public static final Note
MIDDLE_C = new Note("Middle C"),
C_SHARP = new Note("C Sharp"),
B_FLAT = new Note("B Flat");
// Etc.
} ///:~
这段程序实现了一个枚举类Note,它不能生成新的对象(因为ctor是私有的),只能用它固有的三个static对象。
这样的一个类在C++中如何来实现呢?
我的想法是在类中用指针或引用来实现,但在细节的语法层面上还有一些不太清楚的地方,请高手指点一下。谢谢!
...全文
154 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
aflyinghorse 2003-08-12
  • 打赏
  • 举报
回复
我同意你的观点:用引用来实现较好,这样就避免了
用指针导致的堆内存分配不便于释放的问题。

摘自<<Inside The C++ Object Model>>
如果一个临时性对象被绑定于一个reference,对象将残留,
直到被初始化之reference的生命结束,或直到临时对象的
生命范畴(scope)结束--视哪一种情况先到达而定。
lifanxi 2003-08-12
  • 打赏
  • 举报
回复
在Dev中试了一下:
const Note * Note::MIDDLE_C = & Note("Middle C");
会Warning,说是取了临时对象的地址,可以理解.
const Note& Note::MIDDLE_C = Note("Middle C");
可以正常通过.
为此我又查了一下ISO14882,得出结论是对于引用的情况,Note("Middle C")的临时对象要生存到Note::MIDLLE_C对象的生存期结束的时候。所以可以正常运行。不知我这样的理解是否正确?

综上,我个人得出的比较好的做法就是用引用来实现。这样就避免了用指针导致的堆内存分配不便于释放的问题。不知这样的结论是不是能站得住脚?
lifanxi 2003-08-12
  • 打赏
  • 举报
回复
:)英雄所见略同。
不过还是有问题:
如果引用这可这样写的话:
const Note& Note::MIDDLE_C = Note("Middle C");
为什么指针时不能这样写:
const Note * Note::MIDDLE_C = & Note("Middle C");
按理说Note("Middel C")是创建了一个临时的对象,为什么用引用去引用这个临时对象不会出问题,而用指针去指就会出问题呢?(这是我在VS 2003中的试验结果)
还请各位朋友帮忙解释一下。

我手头没有C++沉思录一书,哪位朋友看过的能把上面的实现方法说一下吗?谢谢!


aflyinghorse 2003-08-11
  • 打赏
  • 举报
回复
引用可以这样写吧
#include <iostream>
using namespace std;
class Note {
private:
string noteName;
Note(string noteName) {
this->noteName = noteName;
};
public:
string toString() const { return noteName; }
static const Note & MIDDLE_C;
static const Note & C_SHARP;
static const Note & B_FLAT;
};

const Note& Note::MIDDLE_C = Note("Middle C");
const Note& Note::C_SHARP = Note("C_SHARP");
const Note& Note::B_FLAT = Note("B_FLAT");
int main()
{
cout << Note::MIDDLE_C.toString() << "\n "
<< Note::C_SHARP.toString() << "\n "
<< Note::B_FLAT.toString() << "\n ";

system("pause");
}
aflyinghorse 2003-08-11
  • 打赏
  • 举报
回复
应该由使用者释放把,一时疏忽:) 忘了这件事

int main()
{
cout << Note::MIDDLE_C->toString() << "\n "
<< Note::C_SHARP->toString() << "\n "
<< Note::B_FLAT->toString() << "\n ";

delete Note::MIDDLE_C;
delete Note::C_SHARP;
delete Note::B_FLAT;
system("pause");
}
lifanxi 2003-08-11
  • 打赏
  • 举报
回复
另外,MIDDLE_C,C_SHARP,B_FLAT可以以引用的形式来写吗?
lifanxi 2003-08-11
  • 打赏
  • 举报
回复
谢谢aflyinghorse朋友。
这是我最开始想到的一种实现方法,但我一个疑问是new出来的三个对象的内存释放工作应该由谁来完成呢?编译器会帮我们完成吗?
aflyinghorse 2003-08-11
  • 打赏
  • 举报
回复
程序如下
#include <iostream>
using namespace std;
class Note {
private:
string noteName;
Note(string noteName) {
this->noteName = noteName;
};
public:
string toString() const { return noteName; }
static const Note * MIDDLE_C;
static const Note * C_SHARP;
static const Note * B_FLAT;
};

const Note* Note::MIDDLE_C = new Note("Middle C");
const Note* Note::C_SHARP = new Note("C_SHARP");
const Note* Note::B_FLAT = new Note("B_FLAT");
int main()
{
cout << Note::MIDDLE_C->toString() << "\n "
<< Note::C_SHARP->toString() << "\n "
<< Note::B_FLAT->toString() << "\n ";
system("pause");
}
happycock 2003-08-11
  • 打赏
  • 举报
回复
C++沉思录有例子。就是构造函数私有,声明一个友元,在友元中操作。

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧