繁体   English   中英

C++ 类模板,如何在特定情况下重载 [ ] 运算符?

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

我有一个带有非 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; }
};

在我的 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函数

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

并调用t1.print(); ,

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

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

我是否缺少类模板中的方法? 还是我的重载 [] 运算符实现是错误的?

谢谢!

如果对象上有“const”限定符,则使用“const print”。 否则使用另一种形式。 在您的情况下,“测试”实例都不是“常量”,因此使用非常量版本的打印:

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

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

但在下面的示例中,'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 声明为非常量会导致编译失败,因为您尝试将 const 值取消引用为非常量。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM