C++类模板中,如何在特定研究中重载 [ ] 运算符

C++ class template, how to overload [ ] operator in a specific stuation?

本文关键字:重载 运算符 C++      更新时间:2023-10-16

我有一个带有非 void 类型参数的类模板

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

在我的主文件中.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函数

当我这样做Test& t1 = arr_1[2];

并打电话给t1.print();

它必须使用print()(非常量函数)。

我不明白我如何将 [] 运算符重载到返回一个常量值和一个非常量值。

我的课程模板中是否缺少方法?或者我的重载 [] 运算符实现是错误的?

谢谢!

如果对象上有"const"限定符,则使用"const print"。否则使用其他形式。在您的情况下,没有一个"测试"实例是"const",因此使用非常量版本的打印:

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

在上面的例子中,arr[1] 是 no-const 的,而 t1 也不是,所以两者都将使用 print 的非常量版本。

但在以下示例中,"t2"将是 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();

好吧,在后一种情况下,将 t1 声明为 non-const 将导致编译失败,因为您尝试将 const 值取消对非常量值的引用。

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