gpt4 book ai didi

c++ - 暗示返回值不被存储的方法

转载 作者:行者123 更新时间:2023-12-02 01:44:41 24 4
gpt4 key购买 nike

我们可以使用nodiscard属性来暗示函数的返回值不应被丢弃。是否有任何属性(或其他方式)来暗示一些相反语义:函数的返回值只能临时使用(我的意思是“临时”,不分配给除本地变量之外的任何变量)?

由于目的可能不会立即明确,请考虑我有一个类 FooHolder 来保存资源 Foo;调用 FooHolder::getFoo() 返回当前持有的 Foo:

#include <memory>

class Foo {
public:
Foo& bar() { /* do something */ return *this; }
const Foo& far() const { /* do something else */ return *this; }
};

class FooHolder {
private:
std::shared_ptr<Foo> _foo { nullptr };

public:
FooHolder(): _foo(std::make_shared<Foo>()) {}

Foo& getFoo() { return *_foo; }
const Foo& getFoo() const { return *_foo; }
};

我们可以通过多种方式使用它:

// Others may try storing some status:
Foo* g_foo = nullptr;

int main() {
FooHolder foo_holder {};

// I want to support this:
foo_holder.getFoo().bar().far() /* chained calls... */ ;

// Also, maybe this:
auto& local_foo = foo_holder.getFoo();
local_foo.bar();
local_foo.far();

// But not this, because the Foo instance that FooHolder holds may perish:
static Foo& static_foo = foo_holder.getFoo();

// Nor this:
g_foo = &local_foo;

return 0;
}

那么有没有办法阻止(或至少警告)存储 FooHolder::getFoo() 的返回值?或者,通过引用返回资源是不好的做法吗?

最佳答案

[...] is it bad practice to return resources by reference?

这要看情况。有很多返回非常量引用的方法的示例,它们都很好。例如,考虑标准容器元素访问器。然而,它们并不用于封装。 std::vector::operator[] 并不是要向调用者隐藏元素,而是要提供对其的直接访问。返回非常量引用不是封装!事实恰恰相反。请注意,std::vector 甚至授予您对其 data() 的访问权限。这也不是封装,它依赖于用户不delete[] some_vect.data()或做其他会破坏 vector 的错误事情。

您希望 FooHolder 封装所包含的 Foo

这是相反的要求。

您基本上有两个选择:A) 调用者知道他们在做什么。他们阅读文档。他们知道不应该以错误的方式使用 FooHolder::getFoo。 B) 使用适当的封装:永远不要让调用者直接访问非常量 Foo:

class FooHolder {
private:
std::shared_ptr<Foo> _foo { nullptr };

public:
FooHolder(): _foo(std::make_shared<Foo>()) {}

// nope // Foo& getFoo() { return *_foo; }
// maybe // const Foo& getFoo() const { return *_foo; }

FooHolder& bar() {
_foo->bar();
return *this;
}
// ..same for far() ...
};

请注意,A) 是一个可行的解决方案。考虑一下像 std::shared_ptr 这样的东西也可能被错误地使用。用户应该知道如何正确使用它。不同之处在于 std::shared_ptr 是一个标准类型,具有大量文档。因此,如果这是正确的选择,您应该三思而后行。


So are there ways to prevent (or at least warn about) storing the return value of FooHolder::getFoo()?

没有。一旦你返回了一个非常量引用,所有的赌注都会被取消。 FooHolder 不再控制调用者可以使用该引用执行哪些操作。您可以阻止复制或移动,但无法阻止保留引用。

关于c++ - 暗示返回值不被存储的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71077172/

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