3

次の最小限の例を考えてみましょう。

#include <vector>

class Data
{
    std::vector<int>& v;
public:
    Data(std::vector<int>& _v) : v(_v) {}
    Data(const std::vector<int>& _v) : v(_v) {} // error!
};

int main()
{
    std::vector<int> v;
    const std::vector<int> c_v;
    Data d(v);
    Data const_d(c_v);

    return 0;
}

これはコンパイルされません。下からの全体の出力g++ -Wall

const.cpp: In constructor ‘Data::Data(const std::vector<int>&)’:
const.cpp:8:41: error: invalid initialization of reference of type ‘std::vector<int>&’ from expression of type ‘const std::vector<int>’

理由は明らかです。constキーワードは8行目のキャストに腹を立てています。問題:Dataクラスが必要な場合もありますが、が必要な場合もありstd::vectorますconst std::vector。2つのクラスがあるように:1つはへの読み取りData用、もう1つはからの読み取り用Dataです。ただし、ほとんど冗長な機能を持つ2つのデータクラスを作成するのは好きではありません。私の質問:

  • 私がやろうとしていることをどのように達成できるかについて、良い解決策を教えていただけますmain()か?C++11ソリューションも大歓迎です:)
  • iteratorこれがとの理由const_iteratorですか?
4

2 に答える 2

2

const-データメンバーの性質は、コンパイル時に知る必要があります。constベクトルへの参照が必要な場合とそうでない場合がある場合はconst、共通の機能を含む基本抽象クラスを使用してクラス階層を作成し、それを2つのDataクラスで継承する必要がDataありConstDataます。にはDataconstベクトルConstDataが含まれ、constベクトルが含まれます。この方法では、ロジックを複製することはありませんが、2つの別々のクラスには異なる性質の2つの参照が含まれますconst

次に例を示します。

class AbstractData {
public:
    // Common functions use vect() and const_vect()
    void common_function1();
    void common_function2();
protected:
    virtual vector<int>& vect() const = 0;
    virtual const vector<int>& const_vect() const = 0;
};

class Data : public AbstractData {
    vector<int>& v;
public:
    Data(vector<int>& _v) : v(_v) {}
protected:
    vector<int>& vect() const {
        return v;
    }
    const vector<int>& const_vect() const {
        return v;
    }
};

class ConstData : public AbstractData {
    const vector<int>& v;
    vector<int> temp;
public:
    ConstData(const vector<int>& _v) : v(_v) {}
protected:
    vector<int>& vect() const {
        return temp; // You can choose to throw an exception instead
    }
    const vector<int>& const_vect() const {
        return v;
    }
};

このクラス階層には、使用法に応じて、デストラクタとさまざまなコピーコンストラクタが必要になる場合があることに注意してください。

于 2012-10-27T18:49:08.297 に答える
1

発生したエラーは、次のようなものでした。

foo.cpp: In constructor ‘Data::Data(const std::vector<int>&)’:
foo.cpp:8:44: error: invalid initialization of reference of type ‘std::vector<int>&’ from expression of type ‘const std::vector<int>’

Data...発信者がとして扱われることを()約束したデータへの非定数参照を作成しようとしているためですconst

const参照をDataのメンバーとして宣言するソリューションは次のとおりです。

#include <vector>

class Data
{
    const std::vector<int> &v;
public:
    Data(std::vector<int>& _v) : v(_v) {}
    Data(const std::vector<int>& _v) : v(_v) {} // error!
};

int main()
{
    std::vector<int> v;
    std::vector<int> c_v;
    Data d(v);
    Data const_d(c_v);

    return 0;
}

別のオプションは、代わりに非参照メンバーを使用することです。

#include <vector>

class Data
{
    std::vector<int> v;
public:
    Data(std::vector<int>& _v) : v(_v) {}
    Data(const std::vector<int>& _v) : v(_v) {} // error!
};
于 2012-10-27T18:45:18.533 に答える