gpt4 book ai didi

C++如何避免使用自制的侵入式列表的友元模板函数

转载 作者:行者123 更新时间:2023-11-28 07:08:53 24 4
gpt4 key购买 nike

我需要一个侵入式的、排序的、双链表。我不想使用 boost::intrusive,所以我自己这样做并遇到了问题

对于一个双向链表,有几个操作,这里只是其中一个,这将有助于说明我的观点:

template<typename LIST, typename NODE>
void insertAfter(LIST *list, NODE *node, NODE *newNode)
{
newNode->prev_ = node;
newNode->next_ = node->next_;
if(nullptr == node->next_)
list->last_ = newNode;
else
node->next_->prev_ = newNode;
node->next_ = newNode;
}

现在假设我有一组对象在一个这样的列表中,但我希望它们的内容是私有(private)的:

struct Object
{
private:
Object *prev_, *next_;
};

现在我创建我的列表(请忽略当列表为空时会出现 nullptr 异常的事实......)。

struct List
{
Object *first_, *last_;

void addObject(Object *o)
{
insertAfter(this, last_, o); // not correct when list empty
}
};

这不会编译,因为 prev_ 和 next_ 是私有(private)的并且 insertAfter 没有访问权限。可以很容易地解决这个问题:

// Fwd decl
struct List;

struct Object
{
friend void insertAfter<List, Object>(List *, Object *, Object *);
private:
Object *prev_, *next_;
};

struct List
{
Object *first_, *last_;

void addObject(Object *o)
{
insertAfter(this, last_, o);
}
};

但这会打开一个访问漏洞,任何人都可以使用 insertAfter 来影响 Object 的私有(private)成员。我真正想要的是让 List 成为 Object 的 friend 。我可以通过不为我的链表操作使用模板来解决这个问题(改为使用普通宏),但这显然有其缺点。去这里的正确方法是什么?

最佳答案

按照这些思路怎么样?

template<class ObjectType>
class List
{
ObjectType *first_, *last_;

public:
void addObject(ObjectType *o)
{
insertAfter(this, last_, o);
}

void insertAfter(ObjectType *node, ObjectType *newNode)
{
newNode->prev_ = node;
newNode->next_ = node->next_;
if(nullptr == node->next_)
this->last_ = newNode;
else
node->next_->prev_ = newNode;
node->next_ = newNode;
}
};

class Object
{
private:
Object *prev_, *next_;

friend class List<Object>;
};

int main() {}

不过,我看不出它真的比您已经做的更不令人反感:模板代码无论如何都是内联的,因此您无法阻止人们根据自己的喜好重写您的类。放松一下,对您的客户有一定程度的信任 :)

关于C++如何避免使用自制的侵入式列表的友元模板函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21332150/

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