模板化动态数组中的运算符重载 []

Posted

技术标签:

【中文标题】模板化动态数组中的运算符重载 []【英文标题】:Operator overloading [] in templated Dynamic Array 【发布时间】:2019-06-18 06:12:24 【问题描述】:

我正在尝试重载模板化动态数组中的 [] 运算符,但它似乎没有做任何事情?

我为学校创建了一个模板化的动态数组,我尝试将重载分离到课堂之外。

DynArray.h

template <typename T>
class DynArray

public:
    //The constructor initialises the size of 10 and m_Data to nullptr
    DynArray(void)
    
        m_AllocatedSize = 10;
        m_Data = nullptr;
    

    //deletes m_Data
    ~DynArray()
    
        delete[] m_Data;
        m_Data = nullptr;
    

    T* operator [] (int index)
    
        return m_Data[index];
    

    //creates the array and sets all values to 0
    T* CreateArray(void)
    
        m_Data = new T[m_AllocatedSize];
        m_UsedElements = 0;

        for (int i = 0; i < m_AllocatedSize; ++i)
        
            m_Data[i] = NULL;
        

        return m_Data;
    

private:

    bool Compare(T a, T b)
    
        if (a > b)
            return true;
        return false;
    


    T* m_Data;
    T* m_newData;
    int m_AllocatedSize;
    int m_UsedElements;
;

Main.cpp

#include <iostream>
#include "DynArray.h"
int main()

    DynArray<int>* myArray = new DynArray<int>;
    //runs the create function
    myArray->CreateArray();

    int test = myArray[2];

    delete myArray;
    return 0;

在这种情况下,我希望重载返回 m_Data[2] 处的 int,但它似乎根本没有重载 [],而是显示 no suitable conversion from DynArray&lt;int&gt; to int

【问题讨论】:

您正在创建一个指向单个DynArray 的指针,然后访问不存在的第三个。您可以使用(*myArray)[2] 访问[] 返回的指针,但请记住,它是一个指针,可能不是您想要的。 m_AllocatedSize = 10;m_Data = nullptr; 似乎不对。如果分配的大小是 10,则没有分配任何东西,看起来你正在设置失败。 哦等等,它在CreateArray 中。我推荐阅读What is meant by Resource Acquisition is Initialization (RAII)?。它将帮助您编写更健壮的代码,实际上更简单。 非常感谢,一定会读一读 :) 【参考方案1】:

您返回的指针不是您想要的。你应该这样做:

T& operator [] (const int& index)
  
    return   m_Data[index];
 

另外,myArray 是一个指针,你必须在使用前取消引用它。

int test = (*myArray)[2];

最好不要使用指针:

    int main()// suggested by @user4581301

    DynArray<int> myArray;
    //runs the create function
    myArray.CreateArray();

    int test = myArray[2];


    return 0;

这里没有理由使用指针。

对于动态分配,最好使用smart pointers,而不是newdelete。 这里还有一个问题,你没有检查范围,如果索引是一个负数怎么办。

【讨论】:

谢谢,计划添加范围检查,但是将T* 更改为T&amp; 仍然显示no suitable conversion function from DynArray&lt;int&gt; to int exists 这是因为您的变量是一个指针,编译器会尝试将您的变量解释为数组。尝试不进行堆分配(新) 它仍然是一个指针。这不是使用动态分配的好地方。在您真正需要的时候保存新的。 That's almost never.。试试int main() DynArray&lt;int&gt; myArray; myArray.CreateArray(); int test = myArray[2]; return 0; 吧。 @user4581301 他已经删除了指针。我补充了答案。

以上是关于模板化动态数组中的运算符重载 []的主要内容,如果未能解决你的问题,请参考以下文章

模板化一个类,然后重载运算符 (C++)

在标头之间调用时,模板实例化无法匹配重载流运算符的参数列表

模板赋值运算符重载之谜

对象的动态内存和赋值运算符重载

C++ 作业 - 使用动态数组重载 >> 运算符

引用模板类型的赋值运算符需要非常量重载