重载[]运算符

16

我是一个C++的初学者。我正在学习如何重载操作符。我创建了一个代表复数并具有复杂算术方法的类Complex,以及一个代表复数向量空间C中元素固定长度数组的类ComplexArray

我得到了编译器错误,它无法找到正确的operator[]形式。然而,我在互联网上搜索后仍然无法纠正这个错误。任何指向正确方向的提示/技巧都将极大地帮助我。

严重性 代码 描述 项目 文件 行 抑制状态
错误 C2676 二进制'[':'const ComplexArray'未定义此运算符或类型可接受预定义运算符的转换 ComplexArrays c:\users\quasa\source\repos\complexarrays\complexarrays\testcomplexarray.cpp 7

这是我的代码:

TestComplexArray.cpp

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

Complex ComplexSum(const ComplexArray& cArray, int size)
{
    Complex sum = cArray[0];
    for (int i = 1; i < size; i++)
    {
        sum = sum + cArray[i];
    }
    return sum;
}

Complex ComplexProduct(const ComplexArray& cArray, int size)
{
    Complex product = cArray[0];
    for (int j = 1; j < size; j++)
    {
        product = product * cArray[j];
    }
    return product;
}

int main()
{
    char ch;

    const int size = 5;
    ComplexArray cArray(size);

    for (int i = 0; i < size; i++)
    {
        cArray[i] = Complex((double)(i + 1), 0);
        std::cout << cArray[i];
    }

    Complex sum = ComplexSum(cArray, size);
    Complex product = ComplexProduct(cArray, size);

    std::cout << "Sum = " << sum << std::endl;
    std::cout << "Product = " << product << std::endl;

    std::cin >> ch;
    return 0;
}

复数数组.h

class ComplexArray
{
private:
    Complex* complexArr;
    int size;

    ComplexArray();
public:
    //Constructors and destructors
    ComplexArray(int size);
    ComplexArray(const ComplexArray& source);
    virtual ~ComplexArray();

    //Range for the complexArr
    int MaxIndex() const;

    //Overload the indexing operator
    const Complex& operator [](int index) const;
    Complex& operator [](int index);
};

ComplexArray.cpp

#include "Complex.h"
#include "ComplexArray.h"

ComplexArray::ComplexArray(int s)
{
    size = s;
    complexArr = new Complex[size];
}

ComplexArray::ComplexArray(const ComplexArray& source)
{
    //Deep copy source
    size = source.size;

    complexArr = new Complex[size];

    for (int i = 0; i < size; i++)
    {
        complexArr[i] = source.complexArr[i];
    }
}

ComplexArray::~ComplexArray()
{
    delete[] complexArr;
}

int ComplexArray::MaxIndex() const
{
    return (size - 1);
}

/*
c1.operator[](int index) should return a reference to the Complex
object, because there are two possible cases.

Case 1:
Complex c = complexArray[3];

Case 2:
complexArray[3] = c;

In the second case, complexArray[3] is an lvalue, so it must return
a Complex object  by reference, so that it can be assigned to.
*/

const Complex& ComplexArray::operator[] (int index) const
{
    return complexArr[index];
}

Complex& ComplexArray::operator[](int index)
{
    return complexArr[index];
}

复数.h

#include <iostream>

class Complex
{
private:
    double x;
    double y;
    void init(double xs, double ys); //Private helper function

public:
    //Constructors and destructors
    Complex();
    Complex(const Complex& z);
    Complex(double xs, double ys);
    virtual ~Complex();

    //Selectors
    double X() const;
    double Y() const;

    //Modifiers
    void X(double xs);
    void Y(double ys);

    //Overload binary +, = and * operators
    Complex operator + (const Complex& z);
    Complex& operator = (const Complex& z);
    Complex operator * (const Complex& z) const;

    //Overload unary - operator
    Complex operator -() const;

    friend Complex operator * (const double alpha, const Complex& z);
    friend Complex operator * (const Complex& z, const double beta);

    //Overload << operator
    friend std::ostream& operator << (std::ostream& os, const Complex& z);

    //A complex function f(z)=z^2
    Complex square();
};

3
请注意,您的“ComplexArray”类型使用了您的“Complex”类型,但是“ComplexArray.h”头文件没有包含“Complex.h”头文件。我没有进行测试,但我非常怀疑这一点。 - BoBTFish
10
为什么会有“驾车投票”?这其实是一个非常结构良好的问题,尤其对于一个相当新手的人来说。所有细节都在那里,包括错误信息。可能可以更简洁一些,但代码并不是非常庞大。 - BoBTFish
1
TestComplexArray.cpp会出现未定义类的问题,因为你在ComplexArray之后包含了Complex.h。可以通过前向声明来解决这个问题(除非你忘记展示一个)。 - Swift - Friday Pie
1
@BoBTFish,
  1. 我在 'ComplexArray.h' 中添加了 '#include "Complex.h"'。
  2. 我在 'ComplexArray.cpp' 中添加了 '#include "ComplexArray.h"'。
  3. 我在 'TestComplexArray.cpp' 中添加了 '#include "ComplexArray.h"'。
  4. 我在 ComplexProduct() 和 ComplexSum() 中添加了必要的返回语句。
代码编译成功。
- Quasar
2
现在这篇文章已经进入了 HNQ,恭喜。关于 BoBTFish 在上面提到的“minimal”评论,请参见 [mcve]。 - user202729
显示剩余13条评论
3个回答

11

正如你们所指出的,我错过了 #include 的前置定义。

Complex.cpp 中包含头文件

#include "Complex.h"

ComplexArray.h 包含头文件。

#include "Complex.h"

ComplexArray.cpp有一个头文件。

#include "ComplexArray.h"

TestComplexNumbers.cpp有一个标题

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

我的编译时错误已经被解决。


5
好的回答。最重要的一点是,在 ComplexArray 中使用 Complex 之前必须声明它。这实际上意味着你必须记得在 ComplexArray.h 的顶部包含 "Complex.h" - BoBTFish
1
有时仅仅包含头文件会导致循环包含,通常会导致编译器故障。但也有一些情况下可以使用不完整类型。 - Swift - Friday Pie
明白了!那我会把这个当作最佳实践来做的。 - Quasar

7

我认为错误不是来自 operator[],因为你可以在以下函数中看到:

Complex ComplexSum(const ComplexArray& cArray, int size)
{
    Complex sum = cArray[0];
    for (int i = 1; i < cArray.MaxIndex(); i++)
    {
        sum = sum + cArray[i];
    }
}

没有返回结果是致命的。


6
这绝对是个大问题,但实际上并不是导致问题信息中提到的原因。虽然值得保留回答,但或许可以澄清第一句话。 - BoBTFish

3

ComplexArray 依赖于 Complex,但是 include 的顺序似乎不正确

#include "ComplexArray.h"
#include "Complex.h"

在声明ComplexArray之前,你需要先声明Complex

 class Complex; 

代码在\testcomplexarray.cpp第7行失败,即

 Complex sum = cArray[0];

看起来你遇到了Complex类构造函数的问题。请确保你没有定义这样的构造函数:

 Complex(Complex& v);  // that's bad. it prevents to use copy constructor

如果出于某些难以想象的原因您需要复制构造函数,它应该始终如此:

 Complex(const Complex& v);

为了清晰起见,我添加了 [code]Complex.h[/code] 的头文件。等一下,我正在尝试对复数进行求和和乘法运算。 - Quasar
@Quasar,看起来不错。说实话,我不明白为什么你需要复制构造函数,这看起来像是Straustrup的C++版本中编写的Complex。你在里面做一些错误检查吗,例如在inti()中?如果复制构造函数只是复制字段,那么Complex(const Complex& z) = default;就足够了。 - Swift - Friday Pie
我明白你的意思。我使用的这本书明确声明了所有构造函数。https://www.amazon.in/Introduction-Financial-Engineers-Object-Oriented-Approach/dp/0470015381 - Quasar
@Quasar 啊..而且它有点老了..除非你使用旧编译器。C++11 简化了很多东西。虽然我会说知道 C++98 风格并不会有害,但仍然有一些领域需要它。问题可能是,如果那本书依赖于 C++0x (03),它可能会提到在 C++11 中被删除或更改的语言补充。 - Swift - Friday Pie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接