簡體   English   中英

C++ 運算符過載錯誤

[英]C++ Operator Overload Error

我正在嘗試創建我自己的稱為 safearray 的數組版本,以測試我對運算符重載和創建適當類等的了解。

我遇到了兩個錯誤。

SafeArray.h:11:15: 錯誤:無法重載“const int SafeArray::operator”

SafeArray.h:10:10: 錯誤:使用“int& SafeArray::operator”

我的代碼分為三個文件。

主.cpp

#include <cstdlib>
#include <iostream>

#include "SafeArray.h"

using namespace std;

int main(int argc, char** argv) {

    SafeArray a(10); // 10 integer elements

    for (int i = 0; i < a.length(); i++) {
        cout << i << " " << a[i] << "s" << endl; // values initialise to 0
    }

    cout << endl << a[1]; // Program exits here.

    a[3] = 42;
    cout << a[3];
    a[10] = 10;
    cout << a[10];
    a[-1] = -1; // out-of-bounds is "safe"?

    SafeArray b(20); // another array

    b = a; // array assignment

    for (int i = 0; i < b.length(); i++) {
        cout << b[i] << endl; // values copied from a
    }

    return 0;
}

安全陣列.h

#ifndef SAFEARRAY_H
#define SAFEARRAY_H

class SafeArray {
public:
    SafeArray(int);              // int variable will be the array size
    int length();
    int boundsCheck(int y);       // constructor will call this function
//    const SafeArray operator= (const SafeArray&);
    int& operator[] (int y);
    const int operator [] (const int y); // you need this one too.

    SafeArray &operator=(SafeArray rhs) { 
    std::swap(array, rhs.array);
    std::swap(length_, rhs.length_);
        }

    SafeArray(SafeArray const &other);
    ~SafeArray();
private:
    int length_;
    int *array;
    //int array[];
};

#endif  /* SAFEARRAY_H */

安全陣列.cpp

#include "SafeArray.h"
#include <iostream>

SafeArray::SafeArray(int x) {
    length_ = x;
    array = new int[length];
    for (int i = 0; i < length_; i++) {
        array[i] = 0;
    }
}

int SafeArray::length() {
    return this->length_;
}

int SafeArray::boundsCheck(int y) {

}

int& SafeArray::operator[] (int y) {
    return array[y];
}

SafeArray::~SafeArray() { 
    delete [] array;
}

SafeArray::SafeArray(SafeArray const &other) { 
    int *temp = new int[rhs.size_];
    for (int i=0; i<rhs.size_; i++)
        temp[i] = rhs.array[i];
    std::swap(temp, array);
    delete [] temp;
    return *this;
}

您的 class 定義無效。 int array[]是不完整的類型,不能作為(非靜態)class 成員出現。 一些編譯器接受它作為int array[0]的同義詞,但零大小的 arrays 在 C++ 中也無效(僅在 C99 中)。

簡而言之,您不能按照您的方式編寫代碼。 需要學習動態分配,管理自己的memory。看看std::vector是如何實現的。

在 C++11 中,我可能會推薦一個std::unique_ptr<int[]> array作為快速修復方法,將其初始化為array(new int[x])

實際上 int array[] 是有效的,並且可能顯示為 class 成員。 以下編譯與嚴格的 C++11 一致性:

class foo 
{
public:
    foo() {}
    int length;
    int A[];
};

void ralph()
{
    foo *bar = (foo *)new int[ 21 ];
    bar->length = 20;
    bar->A[0] = 1;
}

這是合法的,並且有其優勢(偶爾)。 雖然不常用。

但是,我懷疑 OP 想要更多的東西

class SafeArray {
public:
    SafeArray(int);              // int variable will be the array size
    int length();
    int boundsCheck(int y);       // constructor will call this function

    int& operator[] (int y);
    const int operator [] (const int y) // you need this one too.
private:
    int length_;
    int *array;
};

隨着

SafeArray::SafeArray(int x) {
    length_ = x;
    array = new int[length];
    for (int i = 0; i < length_; i++) {
        array[i] = 0;
    }
}

正如@Kerrek 已經指出的那樣,您的 class 定義顯然是錯誤的(不應編譯)。

要修復它,您需要將定義更改為:

int *array;

然后在你的默認 ctor 中你可以使用這樣的東西:

SafeArray::SafeArray(unsigned size = 0) 
    : array(new int[size])
{ 
    for (unsigned i=0; i<size; i++)
        array[i] = 0;
}

然后,是的,您需要編寫一個賦值運算符。 通常的方法稱為復制和交換習語。 您創建一個副本,然后將當前副本的內容與副本的內容交換:

SafeArray &operator=(SafeArray rhs) { 
    std::swap(array, rhs.array);
    std::swap(length_, rhs.length_);
}

除此之外,您還需要一個復制構造函數來制作數據的副本:

SafeArray::SafeArray(SafeArray const &other) { 
    int *temp = new int[rhs.size_];
    for (int i=0; i<rhs.size_; i++)
        temp[i] = rhs.array[i];
    std::swap(temp, array);
    delete [] temp;
    return *this;
}

最后,您需要一個析構函數來銷毀 object 並(特別是)刪除它持有的 memory:

SafeArray::~SafeArray() { 
    delete [] array;
}

然后意識到所有這些都是一團糟,永遠不會真正有效。 特別是,基本方法僅限於大小基本固定的數組。 只要您只存儲int ,就很容易忽略這些問題,並制作一個(某種程度上)有效的動態數組。 但是,當/如果您想要存儲其他類型時,您只需要將分配 memory 與初始化該 memory 中的對象分開,這意味着基本上丟棄上面的所有代碼,並將其替換為:

  1. 分別跟蹤數組大小和分配大小
  2. 使用::operator new分配 memory,分配器 object,或其他類似的東西
  3. 在需要時使用 placement new 來初始化 memory 中的對象。
  4. 使用顯式析構函數調用來銷毀對象
  5. 使用::operator delete釋放 memory

等等。 總而言之, std::vector不是一項微不足道的工作。

錯誤消息指的是這兩行:

int& operator[] (int y);
const int operator [] (const int y); // you need this one too.

您的錯誤消息說 (int y) 和 (const int y) 太相似了,不可能是 [] 運算符的兩個不同重載。 您不能在 (int y) 和 (const int y) 上重載,因為這些調用都是模棱兩可的。

如果您的 SafeArray 是常量,您可能打算返回一個 const int,但如果您的 SafeArray 不是常量,則返回一個 int&。 在這種情況下,您聲明第二個 function 以應用於 const SafeArray,方法是將單詞 const 放在參數列表之后。 這是您應該在 SafeArray.h 中編寫的內容:

int& operator[] (int y);
const int operator [] (int y) const; // you need this one too.

然后,您必須在 SafeArray.cpp 中編寫這兩個函數:

int& SafeArray::operator[] (int y) {
    return array[y];
}

const int SafeArray::operator[] (int y) const { // you need this one too.
    return array[y];
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM