【问题标题】:error: passing ‘const Complex’ as ‘this’ argument of '....' discards qualifiers错误:将“const Complex”作为“....”的“this”参数传递会丢弃限定符
【发布时间】:2014-10-21 15:11:24
【问题描述】:

我试图重载 C++ 中的 * 运算符,就复数而言。我还声明了一个常量 I,它位于类文件 (Complex.h) 中。 Complex.cpp 是该类的实现。主文件用于测试。但是,它无法编译。如何解决?

error: passing ‘const Complex’ as ‘this’ argument of ‘Complex Complex::operator*(const Complex&)’ discards qualifiers [-fpermissive]
 cout << "Actual:" << (I * I) << endl;

这是我的主文件:

#include <iostream>
#include "Complex.cpp"  //remove it 
#include "Complex.h"
using namespace std;
int main (){
    // test multiplication
    cout << "\nExpected:I*I = -1" << endl;
    cout << "Actual:" << (I * I) << endl;
    return 0;
}

这是我的头文件:

#ifndef COMPLEX_H
#define COMPLEX_H
#include <cstdlib> //exit
#include <iostream>

class Complex{
    public:
    Complex(double a, double b);
    Complex(double a);
    double real() const{ 
        return a;
    }

    double imag() const{
        return b;
    }
    Complex operator*(const Complex& c2);
    private:
    double a;
    double b;
};

//define a constant i
const Complex I(0,1);
#endif

这是实现文件:

#include "Complex.h"
#include <cmath>

using namespace std;

Complex::Complex(double realNum, double imagNum):a(realNum),b(imagNum){}

Complex::Complex(double realNum):a(realNum),b(0){}

Complex Complex::operator*(const Complex& c2){
    double c = c2.real(), d = c2.imag();
    return Complex((a*c-b*d),(b*c+a*d));
}

【问题讨论】:

    标签: c++ compiler-errors operator-overloading overloading operator-keyword


    【解决方案1】:

    您的声明(I * I) 将两个const Complex 相乘,因此您只能使用该类的const 方法。但是,您的 operator* 仅在非常量版本中可用。

    要更正,只需将其声明为const via

    Complex operator*(const Complex& c2) const;
    

    在实现中也是如此。


    编辑:更详细:您基本上有两种可能性来声明二元运算符,或者在类之外作为

    Complex operator*(Complex const& a, Complex const& b);
    

    或通过

    Complex operator*(Complex const& a) const;
    

    您选择了课堂版本。因此,当编译器看到(I*I)(两者都是const)时,它会将表达式转换为I.operator*(I)。然而,为了这样做,operator* 也必须是const,否则不能从常量I 中调用它。这是因为编译器必须假定该方法将更改I,这是不允许的。

    【讨论】:

    • 为什么说“只能调用 const 方法”?
    • 如果对象是const,则不能调用non-const成员函数。编译器必须假设这些改变了你的类,所以它不再是常量。你可以阅读here 了解 const-correctness。
    • 您正在尝试拨打operator*(const Complex&amp;, const Complex&amp;),而您的接线员是operator*(Complex&amp;, const Complex&amp;)(这只是为了证明一点,实际上可能不是这样)
    • 所以你的意思是, * 函数被认为是一个非访问器,没有放 const。因此,编译器认为我想改变常量 I?
    • 如果成员函数没有标记为const,则允许修改任何成员变量的状态,并且只能传入该类型的非常量变量。这正是您的情况,因为您尝试在 const Complex& 上调用 operator*,但您只为非常量实例提供 operator*
    猜你喜欢
    • 2015-01-13
    • 1970-01-01
    • 2021-11-10
    • 1970-01-01
    • 2018-07-12
    • 1970-01-01
    • 1970-01-01
    • 2020-02-16
    • 1970-01-01
    相关资源
    最近更新 更多