gpt4 book ai didi

C++ - 使用友元关键字来提高效率?

转载 作者:搜寻专家 更新时间:2023-10-31 00:34:53 24 4
gpt4 key购买 nike

例如,我有这两个类(来自 C++ Primer 的练习):

class Message{
set<Folder> folders;
public:
void addFolder(Folder f);
}

class Folder{
set<Message> messages;
public:
void addMessage(Message m);
}

addFolder 方法(等同于 addMessage)是这样的:

void addFolder(Folder f){
folders.push_back(f);
f.addMessage(this);
}

void addMessage(Message m){
messages.push_back(m);
m.addFolder(this);
}

问题是这样我将无限递归调用这两个方法(文件夹添加消息,而不是消息添加文件夹并要求文件夹添加消息等)。

我有两个解决方案:

1.在每个返回 bool 值的类中有一个公共(public)成员,这个值表示给定的消息/文件夹是否在对象的集合中:

void addFolder(Folder f){
folders.push_back(f);
if(!f.search(this)){
f.addMessage(this);
}
}

void addMessage(Message m){
messages.push_back(m);
if(!m.search(this)){
m.addFolder(this);
}
}

这应该可行,但每次我都必须控制 set 两次。

另一个解决方案是在每个类中有一个私有(private)成员,它只添加文件夹/消息而不要求其他人添加它。然后把这个发给类的 friend 。

class Message{
friend class Folder;
set<Folder> folders;
public:
void addFolder(Folder f);
private:
void insertFolder(Folder f){ folders.push_back(f);}
}

class Folder{
friend class Message;
set<Message> messages;
public:
void addMessage(Message m);
private:
void insertMessage(Message m){ messages.push_back(m);}
}

addMessage 和 addFolder 方法将是:

void addFolder(Folder f){
folders.push_back(f);
f.insertMessage(this);
}

void addMessage(Message m){
messages.push_back(m);
m.insertFolder(this);
}

这样不会有递归调用,性能会更好。

这种情况,用friend提高效率可以吗?或者最好使用性能较低的方式(比如搜索方式?)而不使用 friend 关键字?

最佳答案

你的设计有很多错误。您正在递归,因为消息有文件夹,文件夹有消息。您需要比较文件夹和消息,并且没有所有权概念。

您需要暂时忘掉代码,看看数据建模。

您有一组文件夹。我假设每个人都有一个文件夹 ID。您有一组消息。每个都有一个消息 ID。

文件夹和邮件之间存在多对多关系。

给定一个消息 ID,您应该能够看到它包含的所有文件夹。给定一个文件夹 ID,您应该能够看到它包含的所有消息。

我假设“文件夹有消息”,但实际上它只是多对多关系。您可以使用两个多重映射来存储关系。

std::multimap< FolderId, MessageId >;
std::multimap< MessageId, FolderId >;

您还需要常规 map

std::map< FolderId, Folder >;
std::map< MessageId, Message >;

在最后两个映射中,您可以使用智能指针类型来代替FolderMessage,以实现放置和检索。我会简单一点,使用 shared_ptr

除了多重映射,您还可以在每个文件夹/消息对象中只包含一个集合。这只是一个从 Id 到 Id 的映射。然后,您将引用“管理器”,即检索底层对象的主映射。

所以我们可以

class Message
{
std::set< FolderId > folderIds; // folders I am in

// implement construction and access functions etc.
};

typedef std::shared_ptr< Message > MessagePtr;

class Folder
{
std::set< MessageId > messageIds; // messages in this folder
};

typedef std::shared_ptr< Folder > FolderPtr;

将大 map 放入某种管理器

class MessageFolderManager
{
std::map< FolderId, FolderPtr > folders
std::map< MessageId, MessagePtr > messages;
};

请注意,对于依赖项,Folder 和 Message 可能只需要知道其他类型的 ID,而不是其他类型本身。因此,在 Folder.h 中,您将只包含 MessageId 的 header 定义,反之亦然。因此,您不会遇到依赖性问题。管理器需要包括所有类类型。

关于C++ - 使用友元关键字来提高效率?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25200385/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com