2017-10-19 21 views
-1

我有一个非void类型参数C++类模板,如何在特定的stutry中重载[]运算符?

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; 
    } 
}; 

以上是我的模板类以下是一个名为“test”类的类模板。

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; 
} 

我想要做的是,

当我打电话arr_1[1].print();

它使用print() const从我的“测试”类

当我做功能

,并呼吁t1.print();

它使用print()(非const函数)。

我不明白我怎么可以重载[]运算符 返回一个const值和非const值。

我失去了从我的类模板的方法? 或者我的重载[]运算符实现是错误的?

谢谢!

+0

我必须做“试验”类中的测试。感谢您的评论! –

+0

@NeilButterworth,这实际上是我们班的练习题。对不起,没有指定它! –

+0

看来你想要一个表达式'arr_1 [i]'有时候会返回一个const引用,而有时会返回一个非const引用。我不明白这是怎么可能的 - 它怎么知道什么时候返回哪个?当数组中的值实际上是非常量时,为什么要'arr_1 [1] .print();'调用一个常量版本的print()'? –

回答

1

“const的打印”被使用,如果该对象具有在其上的“const”限定符。否则使用其他形式。在你的情况没有“测试”的实例是“常量”,因此打印的非const版本被使用:

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

在上述例子中ARR [1]是没有const的,t1为也不,所以两者都将使用print的非const版本。

在下面的例子虽然,“T2”将是常量,并将使用打印功能的“const版本:

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

在这两种情况下,运营商是非常量。但是如果你把它返回“常量”比这两个变种会使用的打印的“常量”版本:

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

那么,在后一种情况下,宣布T1作为非const会导致编译失败,因为你试试将const值取消为非const。

+0

谢谢你的回答!我不在!这么晚才回复很抱歉。 –

0

您可以让Array::operator[]返回const T&,这将强制const版本的print从返回的引用中调用。但是,在这种情况下,因为你不能没有const_cast分配const引用到一个非const引用行Test& t1 = arr_1[2];会失败。

+0

嗨马克!并感谢您回答我的问题! –

+0

我试着用const T&,并导致同样的问题。这是我决定发布这个问题的主要原因!再次感谢! –