私が設計しているライブラリでは、クラスの大きなメンバ変数への読み込みアクセスが必要なことがあります。彼らのサイズのために、私はメンバーをコピーして返すゲッターを作りたくありません。私はそれらを外部から変更可能にしたくないので、それらを公開したり、それらへの参照を返すことはできません。安全にメンバ変数への参照を返します
class TestClass
{
public:
explicit TestClass(double d): d_(d){}
const double& readD() const { return d_; }
private:
double d_;
};
(これは本当にダブルスのために意図されていない)誰かが参照をconst_castをして、データを直接アクセスすることができ
しかし、ここで:だから私は、私は、「リーダー」を使用するだろうと思いました。悪意を持っていなくても、データメンバへの参照を安全にして、元のオブジェクトが有効範囲外になった後もそのままにしておくことができます。私は、const参照は一時的な実行可能を保つことができますが、const_cast問題は削除されません。 は、だから私は、回避策を思い付いた:
Q1)効率のPOVからこれをどのように必要である:
#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;
}
私はこれまでいくつかの質問がありますか?私が返す最大のオブジェクトは、おそらく1000x1000の次元を持つ密な複雑な行列です。これらのコピーは頻繁に発生する可能性があります
Q2)&の返品に関する懸念はありますか?
Q3)これは良い解決策のようですか?それには欠点がありますか?
'SafeMemberReference'はどのような問題を解決しますか?それは、不必要なコピーを避けることも、 'const_cast'を使って変更を防止することも避けていませんでした。コピーや 'const 'を直接返すこともできます。 – nwp
作業するデータがあります。あなたはそれをカプセル化するクラスを持っています。なぜこのクラスのメソッドとして必要なすべてのデータ操作を実装しないのですか?データへの直接アクセスはありません。 – KonstantinL