重载遇到的问题

寒沙胜雪 2014-02-27 09:29:20
complex.h的

#if ! defined(COMPLEX_H_)
#define COMPLEX_H_

class complex
{
///Attributes:
private:
double real;
double image;
double radius;
double angle;
///Operations:
public:
complex(double real = 0, double image = 0);
complex(const complex &c);
~complex(){};
void setvalue(double real, double image);
double getreal(){return real;}
double getimage(){return image;}
double getradius(){return radius;}
double getangle(){return angle;}
complex operator +(complex comp);
complex operator *(complex comp);
complex operator !();
operator double();
};


#endif




complex.cpp

#include "complex.h"
#include <iostream>
#include <cmath>
using std::cout;
using std::endl;

complex::complex(double real, double image)
{
cout << "Construct Function!" << endl;
setvalue(real, image);
}

complex::complex(const complex &c)
{
cout << "Copy Construct Function!" << endl;
setvalue(c.real, c.image);
}

void complex::setvalue(double real, double image)
{
this->real = real;
this->image = image;
this->radius = sqrt(real * real + image * image);
this->angle = atan2(image, real);
}

complex complex::operator +(complex comp)
{
cout << "+ override function" << endl;
return complex(this->real + comp.real, this->image + comp.image);
}
complex complex::operator *(complex comp)
{
///(a+bi)(c+di) = ac + (ad+bc)i - bd = ac - bd + (ad+bc)i
return complex(this->real * comp.real - this->image * comp.image,
this->real * comp.image + this->image * comp.real);
}
///重载!求复数的共轭复数
complex complex::operator !()
{
return complex(this->real, -this->image);
}
///重载double()求复数的模
complex::operator double()
{
return fabs(radius);
}


main.cpp

#include <iostream>
#include "complex.h"
using std::cin;
using std::cout;
using std::endl;

int main(void )
{
double real1,image1,real2,image2;

cout << "Please the first complex:" << endl;
cin >> real1 >> image1;
cout << "Please the second complex:" << endl;
cin >> real2 >> image2;
complex comp1(real1, image1);
complex comp2(real2, image2);
cout << (comp1+comp2).getreal() << endl;
return 0;
}


不用看完整的类定义,只需要看下重载的+那个函数定义即可,我在main中只用了+做试验,但是用了之后,发现在gcc(code::blocks)下输出这种结果


Please the first complex:
1.1 2.2
Please the second complex:
3.3 4.4
Construct Function!
Construct Function!
Copy Construct Function!
+ override function
Construct Function!
4.4


我明白最后出现Construct Function!是用了RVO(Return Value Optimization),但是在调用重载+函数之前为何会有一个Copy Construct Function!
这是什么原因呢?它拷贝构造的谁呢?
还有一个问题,那就是拷贝构造函数如果在参数中不加const,运行结果会不对,原因是重载了double,但是我在拷贝构造函数里面也没有改变参数的值,为何会有区别呢?

以上两个问题,已困扰多日,希大侠帮忙解决下,谢谢了。
...全文
195 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
寒沙胜雪 2014-03-15
  • 打赏
  • 举报
回复
还是木人呀。。!
寒沙胜雪 2014-03-07
  • 打赏
  • 举报
回复
来个人吧
寒沙胜雪 2014-03-02
  • 打赏
  • 举报
回复
引用 9 楼 vipcxj 的回复:
[quote=引用 8 楼 xiaopo_poxiao 的回复:] [quote=引用 5 楼 vipcxj 的回复:] [quote=引用 1 楼 ganpengjin1 的回复:] (comp1+comp2) 这里产生一个临时对象,调用了你的重载函数+,这个时候return的这个对象将赋值给这个临时对象了。
你阴沟里翻船了~ 那个copy是因为他加法重载里形参传的是对象,而不是引用。还有LZ说的优化我是完全不知道是什么滴个东西,而且还很洋气滴用括号注释了一下,我只知道,LZ的重载加法的return里面明明白白滴调用了构造函数。 说到优化,我觉得return确实是优化了,在函数里面构造的complex直接被返回出了函数外面,并没有再调用copy构造函数,不知道这是标准规定的,还是编译器自己的行为,反正我以前用vs2012试出来,release版本也是这样的。[/quote] 多谢,很抱歉,现在才回。 第一个问题确实是因为我copy构造函数没加引用。 第二个问题怎么回事呢?如果把copy构造函数的const去掉,会在重载+函数里面多调用一次构造函数,运行结果就不对了。而且我在main中只用了getreal,如果把copy构造函数的const去掉,getimage永远都是0.[/quote] http://coliru.stacked-crooked.com/ 你试试这个在线编译器,我复制了你的代码,并且去掉了const,结果根本就编译不了,这说明copy构造函数的const是必须滴。我记得c++11还有个转移构造函数,用的是右值引用,那个才是不加const的。不过想想也对,既然你是copy,那就必然不能修改原始对象,不然就不叫copy了[/quote]

#include <iostream>
#include <cmath>
using std::cin;
using std::cout;
using std::endl;

class complex
{
///Attributes:
private:
    double real;
    double image;
    double radius;
    double angle;
///Operations:
public:
    complex(double real = 0, double image = 0);
    complex(complex &c);
    ~complex(){};
    void setvalue(double real, double image);
    double getreal(){return real;}
    double getimage(){return image;}
    double getradius(){return radius;}
    double getangle(){return angle;}
    complex operator +(complex &comp);
    complex operator *(complex &comp);
    complex operator !();
    operator double();
};

complex::complex(double real, double image)
{
    cout << "Construct Function!" << endl;
    setvalue(real, image);
}

complex::complex(complex &c)
{
    cout << "Copy Construct Function!" << endl;
    setvalue(c.real, c.image);
}

void complex::setvalue(double real, double image)
{
    this->real = real;
    this->image = image;
    this->radius = sqrt(real * real + image * image);
    this->angle = atan2(image, real);
}

complex complex::operator +(complex &comp)
{
    cout << "+ override function" << endl;
    return complex(this->real + comp.real, this->image + comp.image);
}
complex complex::operator *(complex &comp)
{
    ///(a+bi)(c+di) = ac + (ad+bc)i - bd = ac - bd + (ad+bc)i
    return complex(this->real * comp.real - this->image * comp.image,
                   this->real * comp.image + this->image * comp.real);
}
///重载!求复数的共轭复数
complex complex::operator !()
{
    return complex(this->real, -this->image);
}
///重载double()求复数的模
complex::operator double()
{
    return fabs(radius);
}


int main(void )
{
    double real1,image1,real2,image2;
 
    cout << "Please the first complex:" << endl;
    cin >> real1 >> image1;
    cout << "Please the second complex:" << endl;
    cin >> real2 >> image2;
    complex comp1(real1, image1);
    complex comp2(real2, image2);
    cout << (comp1+comp2).getreal() << endl;
	return 0;
}
这代码可以在你说的那网站上通过,只是没法输出。我在vs2012上也能通过。。我做这个程序的时候,忘记了加const,所以出错了,但是加上就对,而且我在copy构造函数里面也没有更改传递过来参数的值,但是为啥加const就对了呢,这正是我纠结之处,希望前辈能细心研究一下,告之结果,鄙人调试水平很低,不太明白。
vipcxj 2014-03-02
  • 打赏
  • 举报
回复
引用 8 楼 xiaopo_poxiao 的回复:
[quote=引用 5 楼 vipcxj 的回复:] [quote=引用 1 楼 ganpengjin1 的回复:] (comp1+comp2) 这里产生一个临时对象,调用了你的重载函数+,这个时候return的这个对象将赋值给这个临时对象了。
你阴沟里翻船了~ 那个copy是因为他加法重载里形参传的是对象,而不是引用。还有LZ说的优化我是完全不知道是什么滴个东西,而且还很洋气滴用括号注释了一下,我只知道,LZ的重载加法的return里面明明白白滴调用了构造函数。 说到优化,我觉得return确实是优化了,在函数里面构造的complex直接被返回出了函数外面,并没有再调用copy构造函数,不知道这是标准规定的,还是编译器自己的行为,反正我以前用vs2012试出来,release版本也是这样的。[/quote] 多谢,很抱歉,现在才回。 第一个问题确实是因为我copy构造函数没加引用。 第二个问题怎么回事呢?如果把copy构造函数的const去掉,会在重载+函数里面多调用一次构造函数,运行结果就不对了。而且我在main中只用了getreal,如果把copy构造函数的const去掉,getimage永远都是0.[/quote] http://coliru.stacked-crooked.com/ 你试试这个在线编译器,我复制了你的代码,并且去掉了const,结果根本就编译不了,这说明copy构造函数的const是必须滴。我记得c++11还有个转移构造函数,用的是右值引用,那个才是不加const的。不过想想也对,既然你是copy,那就必然不能修改原始对象,不然就不叫copy了
寒沙胜雪 2014-03-02
  • 打赏
  • 举报
回复
引用 5 楼 vipcxj 的回复:
[quote=引用 1 楼 ganpengjin1 的回复:] (comp1+comp2) 这里产生一个临时对象,调用了你的重载函数+,这个时候return的这个对象将赋值给这个临时对象了。
你阴沟里翻船了~ 那个copy是因为他加法重载里形参传的是对象,而不是引用。还有LZ说的优化我是完全不知道是什么滴个东西,而且还很洋气滴用括号注释了一下,我只知道,LZ的重载加法的return里面明明白白滴调用了构造函数。 说到优化,我觉得return确实是优化了,在函数里面构造的complex直接被返回出了函数外面,并没有再调用copy构造函数,不知道这是标准规定的,还是编译器自己的行为,反正我以前用vs2012试出来,release版本也是这样的。[/quote] 多谢,很抱歉,现在才回。 第一个问题确实是因为我copy构造函数没加引用。 第二个问题怎么回事呢?如果把copy构造函数的const去掉,会在重载+函数里面多调用一次构造函数,运行结果就不对了。而且我在main中只用了getreal,如果把copy构造函数的const去掉,getimage永远都是0.
寒沙胜雪 2014-03-02
  • 打赏
  • 举报
回复
引用 4 楼 u013225534 的回复:
complex operator +(complex comp);
这传的是复制值,自然在传参数的时候调用了拷贝构造
多谢,很抱歉,现在才回。 第一个问题确实是因为我copy构造函数没加引用。 第二个问题怎么回事呢?如果把copy构造函数的const去掉,会在重载+函数里面多调用一次构造函数,运行结果就不对了。而且我在main中只用了getreal,如果把copy构造函数的const去掉,getimage永远都是0.
寒沙胜雪 2014-03-02
  • 打赏
  • 举报
回复
引用 3 楼 Automation_dmu 的回复:
   complex operator +(complex comp);
改成:
   complex operator +(complex& comp);
多谢,很抱歉,现在才回。 第一个问题确实是因为我copy构造函数没加引用。 第二个问题怎么回事呢?如果把copy构造函数的const去掉,会在重载+函数里面多调用一次构造函数,运行结果就不对了。而且我在main中只用了getreal,如果把copy构造函数的const去掉,getimage永远都是0.
vipcxj 2014-02-28
  • 打赏
  • 举报
回复
引用 1 楼 ganpengjin1 的回复:
(comp1+comp2) 这里产生一个临时对象,调用了你的重载函数+,这个时候return的这个对象将赋值给这个临时对象了。
你阴沟里翻船了~ 那个copy是因为他加法重载里形参传的是对象,而不是引用。还有LZ说的优化我是完全不知道是什么滴个东西,而且还很洋气滴用括号注释了一下,我只知道,LZ的重载加法的return里面明明白白滴调用了构造函数。 说到优化,我觉得return确实是优化了,在函数里面构造的complex直接被返回出了函数外面,并没有再调用copy构造函数,不知道这是标准规定的,还是编译器自己的行为,反正我以前用vs2012试出来,release版本也是这样的。
阳光西西 2014-02-27
  • 打赏
  • 举报
回复
complex operator +(complex comp);
这传的是复制值,自然在传参数的时候调用了拷贝构造
AndyStevens 2014-02-27
  • 打赏
  • 举报
回复
   complex operator +(complex comp);
改成:
   complex operator +(complex& comp);
寒沙胜雪 2014-02-27
  • 打赏
  • 举报
回复
引用 1 楼 ganpengjin1 的回复:
(comp1+comp2) 这里产生一个临时对象,调用了你的重载函数+,这个时候return的这个对象将赋值给这个临时对象了。
但是为啥 Copy Construct Function! + override function 这个拷贝构造函数在重载+函数之前呢?意思就是说它拷贝的谁呢?重载+函数还没有调用,+出来的对象还没有,他怎么拷贝。
漫步者、 2014-02-27
  • 打赏
  • 举报
回复
(comp1+comp2) 这里产生一个临时对象,调用了你的重载函数+,这个时候return的这个对象将赋值给这个临时对象了。

64,683

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧