在我设计的库中,我有时需要读取类的大型成员变量。由于它们的大小,我不想通过复制成员来获得返回的getter。我不希望它们从外部被修改,所以我不能让它们公开或返回对它们的引用。所以我想我会用一个“读者”:安全地返回对成员变量的引用
class TestClass
{
public:
explicit TestClass(double d): d_(d){}
const double& readD() const { return d_; }
private:
double d_;
};
(这是不是真的意味着双打)
但在这里可能会有人的const_cast参考,并直接访问数据。即使没有假定恶意的意图,有人可以安全地引用数据成员,并在原始对象超出范围之后保留它。我知道const引用可以保持临时可行,但是这并不能消除const_cast-问题。 于是我想出了一个解决办法:
#include <iostream>
template<class T>
class SafeMemberReference
{
public:
using type = T;
SafeMemberReference(const T& t) :t(t) {}
explicit SafeMemberReference(T&& t) = delete;
operator const T&() && {return t; }
T get() && {return t; }
private:
const T& t;
};
class TestClass
{
public:
explicit TestClass(double d): d_(d){}
SafeMemberReference<double> readD() const { return d_; }
private:
double d_;
};
int main()
{
TestClass foo(1.2);
// temporary from read can be used as temporary in expressions
std::cout << foo.readD() << std::endl;
// temporary can be used to copy from
auto x = foo.readD().get();
// lvalue can not be used, so a possible dangling reference is no problem
auto ref = foo.readD();
//std::cout << ref << std::endl;
}
我有几个问题是:
Q1)如何就要从效率POV是这样吗?我返回的最大对象是密集复杂矩阵,其维数可能为1000x1000。这些副本可能会发生频繁
Q2)是我对以const &有效恢复的担忧?
Q3)这似乎是一个很好的解决方案吗?它有什么缺点?
SafeMemberReference'解决了什么问题?它既没有解决悬空引用的问题,也没有避免不必要的副本,也没有使用'const_cast'来阻止修改。也可以直接返回一个副本或'const&'。 – nwp
你有数据可以使用。你有一个封装它的类。为什么不实施所有需要的数据操作作为这个类的方法?没有直接访问数据。 – KonstantinL