gpt4 book ai didi

c++ - "Avoid returning handles to object internals",那么有什么选择呢?

转载 作者:IT老高 更新时间:2023-10-28 21:39:32 29 4
gpt4 key购买 nike

Effective C++ by Scott Meyers在第 5 章第 28 项中告诉避免将“句柄”(指针、引用或迭代器)返回到对象内部,这绝对是一个好点。

即不要这样做:

class Family
{
public:
Mother& GetMother() const;
}

因为它破坏了封装并允许更改私有(private)对象成员。

甚至不要这样做:

class Family
{
public:
const Mother& GetMother() const;
}

因为它可能导致“悬空句柄”,这意味着您保留对已销毁对象成员的引用。

现在,我的问题是,有什么好的选择吗?想象妈妈很重!如果我现在返回 Mother 的拷贝而不是引用,GetMother 将成为一项相当昂贵的操作。

你如何处理这种情况?

最佳答案

首先,让我重申一下:最大的问题不是生命周期问题,而是封装问题。

封装不仅仅意味着没有人可以在你不知道的情况下修改一个内部,封装意味着没有人知道你的类是如何实现的,所以你可以随意改变类的内部,只要你保持界面相同。

现在,您返回的引用是否是 const 并不重要:您不小心暴露了 Family 中有一个 Mother 对象这一事实 类,而现在您无法摆脱它(即使您有更好的表示),因为您的所有客户都可能依赖它并且必须更改他们的代码......

最简单的解决方案是按值返回:

class Family {
public:

Mother mother() { return _mother; }
void mother(Mother m) { _mother = m; }

private:
Mother _mother;
};

因为在下一次迭代中我可以删除 _mother 而不会破坏界面:

class Family {
public:

Mother mother() { return Mother(_motherName, _motherBirthDate); }

void mother(Mother m) {
_motherName = m.name();
_motherBirthDate = m.birthDate();
}

private:
Name _motherName;
BirthDate _motherBirthDate;
};

看看我是如何在不改变界面的情况下完全改造内部结构的?轻松愉快。

注意:显然这种转换只是为了效果......

显然,这种封装是以牺牲一些性能为代价的,这里有一个紧张关系,每次编写 getter 时,是否应该首选封装或性能是你的判断。

关于c++ - "Avoid returning handles to object internals",那么有什么选择呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13176751/

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