【问题标题】:Using the constructor to transform variable into object in c++在c++中使用构造函数将变量转换为对象
【发布时间】:2018-11-15 08:39:25
【问题描述】:
 int main()
 {
     CComplex c1(9,9);
     CComplex c3;
     c3 = 5 + c1;    // getting error here
     c3.print();
     cout << c3;

     return 0;
  }

  CComplex CComplex::operator+(const CComplex &complex)
  {
        CComplex temp;
        temp.m_real = complex.m_real + m_real;
        temp.m_imaginary = complex.m_imaginary + m_imaginary;
        return temp;
  }

【问题讨论】:

  • 不确定这是否是骗局:What are the basic rules and idioms for operator overloading?(似乎没有一个答案能解决您需要 2 个运算符重载的问题)
  • 您需要为 int 重载 + 运算符,而不是复杂的。像这样:operator+(int c)
  • 为了将来参考,请说明并解释问题所在,您尝试了什么,并将错误完整附在问题中。
  • @itsundefined 这里需要一个非成员重载operator+(int, CComplex)
  • 他的问题不清楚是否要支持两者

标签: c++ constructor operator-overloading


【解决方案1】:

您需要为int 类型重载+ 运算符并添加一些未定义的构造函数

class CComplex
{
public:
    CComplex()
        : m_real(0), m_imaginary(0)
    { }
    CComplex(double real)
        : m_real(real), m_imaginary(0)
    { }
    CComplex(double real, double imaginary)
        : m_real(real), m_imaginary(imaginary)
    { }

    CComplex operator + (const CComplex& complex)
    {
        CComplex temp;
        temp.m_real = complex.m_real + m_real;
        temp.m_imaginary = complex.m_imaginary + m_imaginary;
        return temp;
    }

    double m_real;
    double m_imaginary;
};


CComplex operator + (const int value, const CComplex& complex)
{
    return CComplex(value) + complex;
}

std::ostream& operator << (std::ostream& os, const CComplex& complex)
{
    os << "(" << complex.m_real << "," << complex.m_imaginary << ")";
    return os;
}


int main()
{
    CComplex c1(9,9);
    CComplex c3;
    c3 = 5 + c1;    // no more error here
    std::cout << c3;
    return 0;
}

结果

(14,9)

【讨论】:

  • 感谢您的快速回复@serge。为什么我们不能在类中定义函数。因为同一个运算符会有两个重载函数。
  • 是的,我们可以 :) 该方法应标记为 friend 用于整数类型重载。
  • 该函数不需要标记为friend。它只使用公共接口。为了在类中定义该函数,它必须是static;否则它将期望 CComplex 作为其左侧参数。
  • @PeteBecker 尝试将其编译为非朋友或静态wandbox.org/permlink/xK6mASKu8XO2IvzP
  • 再次,也许更清楚:friend 将允许它访问私人成员。该函数不使用任何私有成员。在不同范围内定义不同版本的重载可能存在问题,但friend 不是合适的答案。
【解决方案2】:

我认为正确的解决方案是:

class CComplex {
public:
  CComplex();
  CComplex(int);  // NEW - CONVERSION CONSTRUCTOR
  CComplex(double real);
  CComplex(double real, double imaginary);
  friend CComplex operator + (const CComplex& a, const CComplex& b); // FRIEND - NON-MEMBER FUNCTION
};

请注意代码中的这些功能:

  • 有一个构造函数获取一个int 参数。这是一个转换构造函数,编译器可以使用它来自动将 int 转换为 CComplex
  • operator+ 是非成员函数(friend 关键字使函数成为非成员)。它与operator+ 是成员函数(CComplex operator+(CComplex const &amp;b) const)的情况略有不同。

如果你写:

CComplex c1;
5 + c1;

然后对于5 + c1,搜索带有参数(int,CComplex)operator+。根据 C++ 标准,只允许一种转换来获得正确的参数类型(对不起,我没有正式的引用)。有一个从intCComplex 的转换构造函数,所以会自动调用这个转换构造函数,然后用适当的参数调用operator+(CComplex,CComplex)

如果您没有CComplex(int) 构造函数,那么5 + c1 将不起作用,因为需要从intdouble 和从doubleCComplex 的两次转换。

另外,如果operator+ 是成员函数(不是friend),它根本不起作用。因为根据 C++ 标准,左操作数不可能自动转换。所以即使转换构造函数CComplex(int) 也无济于事。

另外:我认为像(int, CComplex) 这样的类型重载operator+ 不是一个好主意,因为它会导致声明爆炸。对于 operator-() 和任何操作数顺序,您都需要相同的 - 例如(CComplex,int)(CComplex,long) 等...通过提供所需类型的转换构造函数,您可以“自动”和“免费”获得所有这些组合。

【讨论】:

    猜你喜欢
    • 2014-11-22
    • 1970-01-01
    • 2012-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-04
    • 2023-03-25
    • 1970-01-01
    相关资源
    最近更新 更多