Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 具有返回值(C+;+;)的函数_C++_Function - Fatal编程技术网

C++ 具有返回值(C+;+;)的函数

C++ 具有返回值(C+;+;)的函数,c++,function,C++,Function,当main()调用返回值为某种数据类型(基元或用户定义)的函数时,调用该函数的语句“通常”是赋值 例:- 假设我的重载“+”的定义如下- complex complex::operator + (complex c) { this->real = this->real + c.real; this->imag = this->imag + c.imag; return *this; } 我的主要功能如下- int main() { com

当main()调用返回值为某种数据类型(基元或用户定义)的函数时,调用该函数的语句“通常”是赋值

例:-

假设我的重载“+”的定义如下-

complex complex::operator + (complex c)
{
    this->real = this->real + c.real;
    this->imag = this->imag + c.imag;
    return *this;
}
我的主要功能如下-

int main()
{
    complex c1;
    complex c2(5,4);
    c1+c2;
}

在上述()中,考虑语句<强> C1+C2< /强>。编译器将其视为c1.operator+(c2)。当main调用此函数时,它将向main()返回一个值。这个返回值会发生什么变化

它被分配到一个时间(如果可以的话是不可见的)复杂值中。该值的生存期是直到生成它的表达式结束,这是;在c1+c2的末尾。因此,将创建一个新的时态对象来存储表达式的结果,并在该行末尾对其进行销毁


您不应该在a+b运算符中修改“this”,在计算a+b之后,现在a保存表达式的结果。

在这种情况下,它会被自动删除(但总和存储在
c1
c2
中)。编译器可能(也可能不)通过完全删除行来优化代码,因为它不会做任何实质性的事情。生成的总和将由
运算符+
构造并返回(将创建一个临时变量),然后立即销毁

这在其他情况下也会发生。考虑这一点:

c2 += c1;
您可以像这样将多个添加链接在一起:

c4 += c3 += c2 += c1;
这是因为
操作符+=
也会返回一个值,但它会像在代码中一样被忽略


顺便说一下,我认为你想使用<代码>运算符+= .< /P> < P>它被简单地丢弃,但是当一个期望返回值的函数没有返回语句时,C++会显示错误。因为您没有将其存储在任何地方

一条重要建议

理想情况下,
operator+
的定义应该如下所示

complex complex::operator + (const complex& c)
{                            ^^^^^^^^^^^^^^
  complex add; 
  add.real = this->real + c.real;
  add.imag = this->imag + c.imag;
  return add;
}
在您的原始代码中,制作了两份
complex
;其中至少有1个参数可以用上述格式避免,其中参数是通过常量引用传递


此外,在代码中不应更改当前对象;(否则它会变成像
操作符+=()
)。因此,在函数内部创建一个临时函数,并按值传递它。

表达式的值
c1+c2
被代码忽略,因为您没有将其存储在任何位置。最多,编译器将打印一些警告消息。要消除此类警告消息,您可以编写:

(void)(c1+c2); //casting to void suppresses the warning messages!
见此:


你的代码的真正问题。。 但是,在代码中,
operator+
的实现在语义上是不正确的。要理解这一点,

 int a=10;
 int b=5;
那么,您是否希望
a+b
更改
a
的值?
a
应该变成
15
?没有

如果您需要,那么您可以编写
a+=b
。但是在您的代码中,
c1+c2
的行为等同于
c1+=c2
的语义,因为您正在更新
this->real
this->imag
的值,这在语义上是不正确的

因此,第一个解决方案是:

complex complex::operator + (const complex& c) const
{                            
  complex result(c); //make a copy of c
  result.real += this->real; //add
  result.imag += this->imag; //add
  return result;
}
现在,这在语义上是正确的

尽管如此,仍有几件事需要注意。当您编写
c1+c2
时,您认为操作
+
是否应用于任何一个对象?不适用。它不适用于其中任何一个,但是成员函数
operator+
在函数内部的
c1
对象上被调用。如果操作不适用于
c1
(或者就此而言
c2
),为什么要调用它

该分析清楚地表明,
operator+
不应该是类的成员函数。它应该是一个非成员函数,然后签名将是:

complex operator+(const complex &a, const complex &b);
但是有一个小问题:在
a+b
的计算中,它需要访问类的私有成员(
real
imag
都是私有成员)。因此,解决方案是,
操作符+
应该按照
操作符+=
来实现,后者应该作为成员函数添加到类中,因为表达式
a+=b
中的
+=
操作在修改其值时适用于
a

下面是我对这两个操作符的实现:

class complex
{
  //...
  public:

    //member function
    complex& operator+=(const complex & c)
    {
          real += c.real; //same as: this->real+=c.real; this is implicit
          imag += c.imag; //same as: this->imag+=c.real; this is implicit
          return *this;
    }
};

//non-member function (its non-friend as well)
complex operator+(const complex &a, const complex &b)
{
    complex result(a); //make copy of a by invoking the copy-constructor
    result += b;  //invokes operator+
    return result;
}
或者,您可以将最后两条语句合并为:

complex operator+(const complex &a, const complex &b)
{
    complex result(a); //make copy of a by invoking the copy-constructor
    return result += b;  //invokes operator+, and then return updated 'result'
}
但还有另一种复制的方法。为什么要通过引用传递这两个参数?通过值传递第一个参数将生成所需的副本。因此,更好的实施方式是:

complex operator+(complex a, const complex &b)
{               //^^^^^^^^^ pass-by-value
    a += b; //a is a copy, after all - we can modify it!
    return a;
}

希望能有所帮助。

另一个解决方案是在全局范围内使用
操作符+
,但作为您班上的朋友:

class complex
{
    // ...

public:

    // ...

    friend complex operator +(const complex &c1, const complex &c2)
    {
        complex c;
        c.real = c1.real + c2.real;
        c.imag = c1.imag + c2.imag;
        return c;
    }

    // ...

};
使用此技术,您还可以使用整数作为参数(在lhs处),方法是添加:

    friend complex operator +(const int n, const complex &c)
    {
        complex c;
        c.real = n + c.real;
        c.imag = c.imag;
        return c;
    }

    friend complex operator +(const complex &c, const int n)
    {
        complex c;
        c.real = c.real + n;
        c.imag = c.imag;
        return c;
    }
所以现在你也可以做了

 complex c1, c2, c3;
 c3 = 1 + c2 + 8 + c1 + 2;

如果您的类缺少一个(虚拟)析构函数,我也会将成员变量设置为受保护的,而不是私有的:)

不要像那样重载
操作符+
。你能想象如果说
y=x+7
修改了
x
的值吗?@Travis。。谢谢你的建议:)。。我明白。但我是C++初学者,尝试用各种方法来探索事物。不要通过传递rhs by值来重载+运算符。通过引用传递它。也就是说,将函数声明为“complex&complex::operator+(complex&c)”。您的
operator+
看起来应该是
operator+=
。这就是你对
real
imag
成员所做的:复合赋值。@Luc Danton:没错。我在详细的回答中已经解释过了。但是
 complex c1, c2, c3;
 c3 = 1 + c2 + 8 + c1 + 2;