2017-10-19 10 views
-1

私は非void型のパラメータC++クラスのテンプレート、特定のstuationで[]演算子をどのようにオーバーロードするのですか?

template <typename T, unsigned int n> 
class Array 
{ 
private: 
    T* value; 
public: 
    Array() 
    { 
     this->value = new T[n]; 
    } 

    ~Array() { 
     delete [] this->value; 
    } 
    Array(const Array & arr){ 
     this->value = new T[n]; 
     int a = n; 
     int b = 0; 
     while(a != 0) 
     { 
      this->value[b] = arr.value[b]; 
      b++; 
      a--; 
     } 
    } 
    Array& operator=(const Array& arr) 
    { 
     int a = n; 
     int b = 0; 
     while(a != 0) 
     { 
      this->value[b] = arr.value[b]; 
      b++; 
      a--; 
     } 
     return *this; 
    } 

    T& operator[](int a) 
    { 
     return this->value[a]; 
    } 

    unsigned int size() 
    { 
     return n; 
    } 
}; 

上記の私のクラステンプレートであり、以下「テスト」という名前のクラスがあるとクラステンプレートを持っています。私はarr_1[1].print();を呼び出すとき

class Test 
{ 
public: 
    Test() { std::cout << "Test::Test()" << std::endl; } 

    Test(Test const&) { std::cout << "Test::Test(Test const&)" << std::endl; } 

    ~Test() { std::cout << "Test::~Test()" << std::endl; } 

    Test& operator=(Test const&) 
    { 
     std::cout << "Test& Test::operator=(Test const&)" << std::endl; 
     return *this; 
    } 

    void print() const { std::cout << "Test::print() const" << std::endl; } 
    void print() { std::cout << "Test::print()" << std::endl; } 
}; 

そして、私のmain.cppにファイルで、私は私が何をしたいのか、この

int main(int, char*[]) 
{ 
    Array<Test, 3> arr_1; 
    arr_1[1].print(); 

    Test& t1 = arr_1[2]; 
    t1.print(); 

    return 0; 
} 

を書いたが、

で、

それを使用する必要がありprint() const私の "Test"クラスの関数

と私が行ったときTest& t1 = arr_1[2];

t1.print();呼び出し、

それはprint()(非const関数)を使用する必要があります。

[]演算子を にオーバーロードする方法が分かりません。const値と非const値を返します。

私のクラステンプレートのメソッドがありませんか? または、私のoverload []演算子の実装が間違っていますか?

ありがとうございました!

+0

私は "テスト"クラスでテストを行う必要があります。あなたのコメントをありがとう! –

+0

@ NeeButterworth、それは実際に私のクラスの練習問題です。それを指定しないと申し訳ありません! –

+0

'arr_1 [i]'という式は時々const参照と非const参照を別の時に返すようにしたいと思うようです。私はこれがどのように可能であるかはわかりません - いつどのようなものを返すのかを知っていますか?配列の値が実際に非constの場合、なぜ 'arr_1 [1] .print();'が 'print()'のconstバージョンを呼びたいのですか? –

答えて

1

オブジェクトに 'const'修飾子がある場合、 'const print'が使用されます。それ以外の場合は、別の形式が使用されます。あなたのケースでは「試験」インスタンスのどれも「CONST」がないので、印刷の非constバージョンが使用される:

T& operator[](int a) 
... 
arr[1].print(); 
Test &t1 = arr[2]; 
t1.print(); 

上記の実施例[1]無CONSTなく、t1はないか、ARRしたがって、両方とも非constバージョンの印刷を使用します。次の例で

しかし、「T2」はCONSTとなり、印刷機能の「constのバージョン使用します。両方の場合において、オペレータは、非constである

T& operator[](int a) 
... 
arr[1].print(); 
const Test &t2 = arr[2]; 
t2.print(); 

を。あなたは、両方の変異体は、印刷の「CONST」バージョンを使用するよりも、それは「CONST」を返すようにしますただし場合:

const T& operator[](int a) 
... 
arr[1].print(); 
const Test &t1 = arr[2]; 
t1.print(); 

さて、あなたがしようとしているため、コンパイルの故障の原因となります非constとしてT1を宣言後者の場合const値を非constにデフレクセーションする。

+0

ありがとうございました!私は離れていた!返事が遅れて申し訳ありません。 –

0

Array::operator[]を返すとconst T&が返され、constバージョンのprintが返された参照から強制的に呼び出されます。しかし、その場合はという行は、const参照をconst_castなしで非const参照に割り当てることができないので失敗します。

+0

こんにちは!私の質問に答えてくれてありがとう! –

+0

const T&で試したところ、同じ問題が発生しました。それが私がこの質問を投稿することを決めた主な理由です!もう一度! –

関連する問題