クラスのメンバーとしてベクターを持っているので、後で変更できるように、getVector()関数を使用してベクターへの参照を返します。関数getVector()をconstにしたほうがよいのではないでしょうか?ただし、次のコードで「型のバインディング参照で修飾子が削除されました...」というエラーが発生しました。何を変更する必要がありますか?
class VectorHolder
{
public:
VectorHolder(const std::vector<int>&);
std::vector<int>& getVector() const;
private:
std::vector<int> myVector;
};
std::vector<int> &VectorHolder::getVector() const
{
return myVector;
}
これはconst
メンバー関数であるため、戻り値の型を非const参照にすることはできません。 const
にする:
const std::vector<int> &VectorHolder::getVector() const
{
return myVector;
}
今は大丈夫です。
なぜ大丈夫ですか? const
メンバー関数では、すべてのメンバーがconstになり、変更できないようになります。つまり、myVector
はconst
になります。関数内のベクトル。これがreferenceを返す場合、戻り型const
も作成する必要がある理由です。
ここで、cannotを変更しますsameオブジェクト。できることとできないことを確認してください。
std::vector<int> & a = x.getVector(); //error - at compile time!
const std::vector<int> & a = x.getVector(); //ok
a.Push_back(10); //error - at compile time!
std::vector<int> a = x.getVector(); //ok
a.Push_back(10); //ok
ところで、そもそもなぜこのようなVectorHolder
が必要なのか疑問に思っています。
次のように、constとmutableの両方のバリアントを宣言することは珍しいことではありません。
std::vector<int>& VectorHolder::getVector() {
return myVector;
}
const std::vector<int>& VectorHolder::getVector() const {
return myVector;
}
プログラムの根本的な問題は、constメソッドから非const参照を返すことです。
std::vector<int>& VectorHolder::getVector() const {
return myVector; // << error: return mutable reference from const method
}
したがって、次の形式を使用してconstにします。
const std::vector<int>& VectorHolder::getVector() const {
return myVector; // << ok
}
これが非constメソッドにある場合、またはクライアントが非const参照を保持している場合は、非constメソッドを合法的に使用できます。
std::vector<int>& VectorHolder::getVector() {
return myVector; // << ok
}
最後に、値を返すことができます(場合によって):
std::vector<int> VectorHolder::getVector() const {
return myVector; // << ok
}
コピーには突然変異が不要であり、内部データにさらされないためです。
そのため、両方のバリアントを頻繁に宣言することになります。
両方を宣言した結果は次のとおりです。
VectorHolder m;
const VectorHolder c;
m.getVector().size(); // << ok
c.getVector().size(); // << ok - no mutation
m.getVector().Push_back(a); // << ok
c.getVector().Push_back(a); // << error: attempt to mutate const reference because the const vector is returned
そのため、すべてがうまく機能します(メソッドの冗長性は別として)。
関数getVector
は、const
として宣言できます。変更可能な参照が返されるため、実際の関数はクラス内の何も変更しませんが、呼び出し元は内部データを変更できます。
次のように宣言します。
std::vector<int>& getVector();
変更できないベクトルを関数で返すには、ベクトルと関数の両方でconst
修飾子を使用します。
const std::vector<int>& getVector() const;
その理由は、constメンバー関数はconst参照のみを返す必要があるためです。これは、const関数では、すべてのデータメンバーが定数になるためです。
したがって、このようにgetVector()を宣言する必要があります。
std::vector<int> &VectorHolder::getVector() const;