两个类互相作为类型使用的问题
以下是C++ PRIMER中文第四版13章里消息处理机制中的课后习题,我自己扩充了下,出现了一些问题,主要是在类Message中使用了类Folder,编译器把类型当作Message::Folder来处理了,由此造成很多编译错误。我的文件代码如下:
定义类的头文件Message.h
#include <string>
#include <set>
#ifndef MESSAGEH
#define MESSAGEH
class Message
{
public:
class Folder;
Message(const std::string &str = ""):
contents (str) {}
Message(const Message&);
Message& operator=(const Message&);
~Message();
void save(Folder&);
void remove(Folder&);
std::string Show()
{ return contents; }
private:
std::string contents;
std::set<Folder*> folders;
void put_Msg_in_Folders(const std::set<Folder*>&);
void remove_Msg_from_Folders();
};
class Folder
{
public:
void remMsg(Message*);
void addMsg(Message*);
unsigned MsgNum();
std::string ShowMsg(unsigned);
private:
std::set<Message*> messages;
};
#endif
编写定义类的函数等具体文件Message.cpp
#include "Message.h"
#include <string>
#include <set>
Message::Message(const Message &ms):
contents(ms.contents), folders(ms.folders)
{ put_Msg_in_Folders(folders); }
Message& Message::operator=(const Message &ms)
{
if (&ms != this)
{
remove_Msg_from_Folders();
contents = ms.contents;
folders = ms.folders;
put_Msg_in_Folders(ms.folders);
}
return *this;
}
void Message::put_Msg_in_Folders(std::set<Folder*> &sf)
{
for (std::set<Folder*>::iterator beg = sf.begin();
beg != sf.end(); ++beg)
(*beg)->addMsg(this);
}
void Message::remove_Msg_from_Folders()
{
for (std::set<Folder*>::iterator beg = folders.begin();
beg != folders.end(); ++beg)
(*beg)->remMsg(this);
}
void Message::save(Folder &fds)
{
//如果该邮件的文件夹列表中没有这个文件夹,则将该文件夹添加到邮件的文件夹集合
if (!folders.count(&fds))
folders.insert(&fds);
//如果形参文件夹尚未保存该邮件指针,则予以保存
if (!(fds->messages).count(this))
(fds->messages).insert(this);
return;
}
void Message::remove(Folder &fds)
{
if (folders.count(&fds))
folders.erase(&fds);
if ((fds->messages).count(this))
(fds->messages).erase(this);
return;
}
Message::~Message()
{ remove_Msg_from_Folders(); }
编写类Folder函数代码的文件Folder.cpp
#include "Message.h"
#include <set>
#include <string>
#include <iostream>
void Folder::remMsg(Message *mp)
{
if (messages.count(mp))
messages.erase(mp);
return;
}
void Folder::addMsg(Message *mp)
{
if (!messages.count(mp))
messages.insert(mp);
return;
}
unsigned Folder::MsgNum()
{
unsigned sum(0);
std::set<Message*>::const_iterator beg = messages.begin();
while (beg != messages.end())
{
++sum;
++beg;
}
return sum;
}
std::string Folder::ShowMsg(unsigned ix)
{
unsigned num(0);
std::set<Message*>::const_iterator beg = messages.begin();
if (beg == messages.end()){
std::cout << "该邮件夹中没有任何邮件!" << std::endl;
return std::string("Error!\n");
}
while (beg != messages.end())
{
if (num == ix)
break;
else
{
++num;
++beg;
}
}
if (num != ix){
std::cout << "超出邮件数量范围!" << std::endl;
return std::string("Out of range!\n");
}
else{
return (*beg)->Show();
}
}
测试文件main.cpp
#include "Message.h"
#include <string>
#include <iostream>
#include <vector>
using namespace std;
int main()
{
Folder MySelf, EveryOne;
vector<Message> msg;
while (true)
{
cout << "下面请写信:" << endl;
string msgtxt;
cin >> msgtxt;
msg.push_back(Message(msgtxt));
cout << "你想将信件保存在那个文件夹?(1:MySelf;2:EveryOne)" << endl;
unsigned folderName;
cin >> folderName;
if (folderName == 1)
msg.back().save(MySelf);
else msg.back().save(EveryOne);
cout << "还想继续写信吗?(y 或 n)" << endl;
char next;
cin >> next;
if (next == 'n')
break;
}
cout << "现在你的MySelf邮件夹中有:" << MySelf.MsgNum()
<< "封邮件!\n你的EveryOne邮件夹中有:"
<< EveryOne.MsgNum() << "封邮件!" << endl;
return 0;
}
[解决办法]
class Message {
public:
class Folder;
将class Folder; 声明放到class Message 类的外面
class Folder;
class Message {
public:
[解决办法]
Folder明明是个嵌套类,即Message::Folder,你在Folder.cpp中的定义应加上:Message::Folder::xxx