C ++运算符重载错误

时间:2012-04-03 23:40:16

标签: c++

我正在尝试创建我自己的一个名为safearray的数组版本,以测试我对运算符重载的知识并创建正确的类等。

我遇到两个错误。

SafeArray.h:11:15:错误:'const int SafeArray :: operator'不能重载

SafeArray.h:10:10:错误:使用'int&的SafeArray ::运算符”

我的代码分为三个文件。

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

SafeArray.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 */

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

4 个答案:

答案 0 :(得分:3)

您的班级定义无效。 int array[]是一个不完整的类型,它不能作为(非静态)类成员出现。有些编译器接受这个作为int array[0]的同义词,但零大小的数组在C ++中也无效(仅在C99中)。

简而言之,您无法按照自己的方式编写代码。您需要了解动态分配并管理自己的内存。查看std::vector的实施方式。

在C ++ 11中,我可能会建议使用std::unique_ptr<int[]> array作为快速修复方法,将其初始化为array(new int[x])

答案 1 :(得分:0)

实际上int array []是有效的,并且可能显示为类成员。以下编译符合严格的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;
    }
}

答案 2 :(得分:0)

正如@Kerrek已经指出的那样,你的类定义显然是错误的(不应该编译)。

要修复它,您需要将定义更改为:

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

最后,你需要一个析构函数来销毁一个对象,并(特别是)删除它所拥有的内存:

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

然后意识到所有这一切都是丑陋的混乱,永远不会真正奏效。特别是,基本方法仅限于基本固定大小的数组。只要您只存储int,就可以很容易地忽略这些问题,并制作一个(某种程度上)有效的动态数组。当/如果你想存储其他类型时,你只需要分配内存与初始化该内存中的对象,这意味着丢弃上面的所有代码,并用以下内容替换它:

  1. 分别跟踪数组大小和分配大小
  2. 使用::operator new,Allocator对象或其他类似的
  3. 分配内存
  4. 在需要时使用placement new来初始化内存中的对象。
  5. 使用显式析构函数调用来销毁对象
  6. 使用::operator delete释放内存
  7. 等等。总而言之,std::vector 是一项微不足道的工作。

答案 3 :(得分:0)

错误消息指的是这两行:

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,你可能想要返回一个const int,但是返回一个int&amp;如果你的SafeArray不是const。在这种情况下,通过在参数列表后面添加单词const,声明要应用于const SafeArray的第二个函数。这是您应该在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];
}