VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

搜索
查看: 1260|回复: 11

类的新手,为什么间接调用下结果就不一样

[复制链接]
06_avatar_middle
最佳答案
0 
在线会员 发表于 2020-6-30 12:04:29 | 显示全部楼层 |阅读模式
//add成员函数都是调用setcomplexnumber,为什么通过构造函数间接调用setcomplexnumber和直接调用setcomplexnumber结果会不一样

#include <iostream>
#include <cmath>
using namespace std;

class Complex{
public:
    Complex(double =1.0,double=1.0);
    void add(Complex const &);
    void print();
    void setcomplexnumber(double,double);
private:
    double realpart,imaginarypart;
};

Complex::Complex(double re,double im)
{
    setcomplexnumber(re,im);
}

void Complex::add(const Complex &ri)
{
    //setcomplexnumber(realpart+ri.realpart,imaginarypart+ri.imaginarypart); //为什么改成这行可以得到是4和7
    Complex(realpart+ri.realpart,imaginarypart+ri.imaginarypart);   //改成这行变成1和1了
}

void Complex::print()
{
    cout<<"("<<realpart<<","<<imaginarypart<<")";
}

void Complex::setcomplexnumber(double r,double i)
{
    realpart=r;
    imaginarypart=i;
}

int main()
{
    Complex a(4,5);
    Complex b(3,6);
    Complex c;
    a.print();
    cout<<"+";
    b.print();
    cout<<"=";
    c.add(b);
    c.print();
    return 0;
}




上一篇:关于VC++的CheckBox控件
下一篇:MFC工业控制的案例或视频
70_avatar_middle
最佳答案
49 
在线会员 发表于 2020-7-1 08:54:29 | 显示全部楼层
Complex(realpart+ri.realpart,imaginarypart+ri.imaginarypart);   //改成这行变成1和1了
这行并没有改变c 的值啊,他本来就是1,1
06_avatar_middle
最佳答案
0 
ico_lz  楼主| 发表于 2020-7-1 10:00:48 | 显示全部楼层
改了
void Complex::add(const Complex &ri)
{
    //setcomplexnumber(realpart+ri.realpart,imaginarypart+ri.imaginarypart); //为什么改成这行可以得到是4和7
    Complex(realpart+ri.realpart,imaginarypart+ri.imaginarypart);   //改成这行变成1和1了
}
通过调用构造函数间接调用  setcomplexnumber函数向  realpart和 imaginarypart赋值  ,按道理c.print()函数应该输入出  realpart和imaginarypart被改变后的值而不是默认值
你看默认构造函数是间接调用setcomplexnumber函数 ,和直接调用setcomplexnumber作用是一样的,但直接调用setcomplexnumber和通过构造函数间接调用setcomplexnumber值用 c.print()显示时结果是不一样,为什么间接和直接结果会不一样
06_avatar_middle
最佳答案
0 
ico_lz  楼主| 发表于 2020-7-1 10:02:56 | 显示全部楼层
tony666 发表于 2020-7-1 08:54
Complex(realpart+ri.realpart,imaginarypart+ri.imaginarypart);   //改成这行变成1和1了
这行并没有改变 ...

改了

通过调用构造函数间接调用  setcomplexnumber函数向  realpart和 imaginarypart赋值  ,按道理c.print()函数应该输入出  realpart和imaginarypart被改变后的值而不是默认值
你看默认构造函数是间接调用setcomplexnumber函数 ,和直接调用setcomplexnumber作用是一样的,但直接调用setcomplexnumber和通过构造函数间接调用setcomplexnumber值用 c.print()显示时结果是不一样,为什么间接和直接结果会不一样
70_avatar_middle
最佳答案
49 
在线会员 发表于 2020-7-1 10:55:07 | 显示全部楼层
不太能理解你说的什么意思,你这个c.add(b)逻辑的问题吧
这是你想要的效果吗?
  1. #include <iostream>
  2. #include <cmath>
  3. using namespace std;

  4. class Complex {
  5. public:
  6.     Complex(double = 1.0, double = 1.0);
  7.     void add(Complex const&);
  8.     void print();
  9.     void setcomplexnumber(double, double);
  10. private:
  11.     double realpart, imaginarypart;
  12. };

  13. Complex::Complex(double re, double im)
  14. {
  15.     setcomplexnumber(re, im);
  16. }

  17. void Complex::add(const Complex& ri)
  18. {
  19.     setcomplexnumber(realpart+ri.realpart,imaginarypart+ri.imaginarypart); //为什么改成这行可以得到是4和7
  20.     //Complex(realpart + ri.realpart, imaginarypart + ri.imaginarypart);   //改成这行变成1和1了
  21. }

  22. void Complex::print()
  23. {
  24.     cout << "(" << realpart << "," << imaginarypart << ")";
  25. }

  26. void Complex::setcomplexnumber(double r, double i)
  27. {
  28.     realpart = r;
  29.     imaginarypart = i;
  30. }

  31. int main()
  32. {
  33.     Complex a(4, 5);
  34.     Complex b(3, 6);
  35.     Complex c(0,0);
  36.     a.print();
  37.     cout << "+";
  38.     b.print();
  39.     cout << "=";
  40.     c.add(a);
  41.     c.add(b);
  42.     c.print();
  43.     return 0;
  44. }
复制代码
57_avatar_middle
最佳答案
25 
在线会员 发表于 2020-7-1 11:27:00 | 显示全部楼层
本帖最后由 JLDawson 于 2020-7-1 11:32 编辑

1.无名对象,也叫临时对象。指的是直接由构造函数产生,但是没有被任何符号所引用的对象。例如:Complex(realpart+ri.realpart,imaginarypart+ri.imaginarypart);这句话产生的就是一个无名对象,这个对象产生以后,没有什么办法使用它。但是对于Complex a(4,5);来说,则产生的是一个有名字的对象,他的名字就是 a。
在这个基础上我们来看你的代码:
Complex(realpart + ri.realpart, imaginarypart + ri.imaginarypart);//声明了一个无名对象,无名对象在他的构造函数中调用了无名对象的成员函数setcomplexnumber对成员变量进行赋值。无名对象的成员变量分别被修改为4,7。
你的代码理解下来就是:c的add函数中你定义了一个无名对象,并对无名对象的成员变量进行赋值。之后你去打印c的成员变量。期间你对c的成员变量并没有进行修改。
  1. #include <iostream>
  2. #include <cmath>
  3. using namespace std;

  4. class Complex {
  5. public:
  6.         Complex(double = 1.0, double = 1.0,string sName = "");
  7.         void add(Complex const&);
  8.         void print();
  9.         void setcomplexnumber(double, double);

  10. private:
  11.         double realpart, imaginarypart;
  12.         string sName;
  13. };

  14. Complex::Complex(double re, double im, string sName)
  15.         :sName(sName)
  16. {
  17.         setcomplexnumber(re, im);

  18.         cout << sName.c_str()<< ": " << realpart << imaginarypart << endl;
  19. }

  20. void Complex::add(const Complex& ri)
  21. {
  22.         //setcomplexnumber(realpart + ri.realpart, imaginarypart + ri.imaginarypart); //为什么改成这行可以得到是4和7
  23.         Complex(realpart + ri.realpart, imaginarypart + ri.imaginarypart,"noname");   //改成这行变成1和1了
  24. }

  25. void Complex::print()
  26. {
  27.         cout << "(" << realpart << "," << imaginarypart << ")" << endl;
  28. }

  29. void Complex::setcomplexnumber(double r, double i)
  30. {
  31.         realpart = r;
  32.         imaginarypart = i;
  33. }

  34. int main()
  35. {
  36.         Complex a(4, 5,"a");
  37.         Complex b(3, 6,"b");
  38.         Complex c(1,1,"c");
  39.         a.print();
  40.         cout << "+" << endl;
  41.         b.print();
  42.         cout << "=" << endl;
  43.         c.add(b);
  44.         c.print();
  45.         return 0;
  46. }
复制代码

输出结果为:
  1. a: 45
  2. b: 36
  3. c: 11
  4. (4,5)
  5. +
  6. (3,6)
  7. =
  8. noname: 47
  9. (1,1)
复制代码

写代码多写几行,多点打印,这样才能更清晰。基础书多看看,最好边看边写代码,互相验证。
(你之前发了几个悬赏提问帖子,我看都有人回复的很明白了。你怎么没有结束提问,并把悬赏发给回答者?)
06_avatar_middle
最佳答案
0 
ico_lz  楼主| 发表于 2020-7-1 15:48:51 | 显示全部楼层
tony666 发表于 2020-7-1 10:55
不太能理解你说的什么意思,你这个c.add(b)逻辑的问题吧
这是你想要的效果吗?

c.add(b)    是把b这个对象用引用方式在c.add这个成员函数中理行加法处理
06_avatar_middle
最佳答案
0 
ico_lz  楼主| 发表于 2020-7-1 16:11:06 | 显示全部楼层
JLDawson 发表于 2020-7-1 11:27
1.无名对象,也叫临时对象。指的是直接由构造函数产生,但是没有被任何符号所引用的对象。例如:Complex(re ...

为什么说这行Complex(realpart + ri.realpart, imaginarypart + ri.imaginarypart,"noname");   会产生临时对象啊,在我看来这个是调用函数,怎么会变成创建临时对象

06_avatar_middle
最佳答案
0 
ico_lz  楼主| 发表于 2020-7-1 17:33:42 | 显示全部楼层
本帖最后由 xiethree 于 2020-7-1 17:47 编辑

搜索下,懂了,晕,看的书里没写到这个特点,谢谢各位

如果要把这个临时对象值拷出来要怎么操作
void Complex::add(const Complex &ri)
{
    //setcomplexnumber(realpart+ri.realpart,imaginarypart+ri.imaginarypart);
    Complex(realpart+ri.realpart,imaginarypart+ri.imaginarypart);  
}
57_avatar_middle
最佳答案
25 
在线会员 发表于 2020-7-1 17:50:47 | 显示全部楼层
本帖最后由 JLDawson 于 2020-7-1 17:54 编辑
xiethree 发表于 2020-7-1 16:11
为什么说这行Complex(realpart + ri.realpart, imaginarypart + ri.imaginarypart,"noname");   会产生临 ...


此处的Complex并不是Complex类的构造函数而是Complex类名。
比如int(1),int是内置类型名称,(1)是传参。同理。
Complex是一个自定义类型,他有构造函数 Complex(double = 1.0, double = 1.0);
如何声明定义一个变量(对象),类型名称 对象名称。
以下是构造函数的定义。重点是这句:它会在每次创建类的新对象时执行。
  1. 类的构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行。
  2. 构造函数的名称与类的名称是完全相同的,并且不会返回任何类型,也不会返回 void。构造函数可用于为某些成员变量设置初始值。
复制代码

57_avatar_middle
最佳答案
25 
在线会员 发表于 2020-7-1 18:57:29 | 显示全部楼层
xiethree 发表于 2020-7-1 17:33
搜索下,懂了,晕,看的书里没写到这个特点,谢谢各位

如果要把这个临时对象值拷出来要怎么操作

你去搜索一下无名对象,然后再考虑自己想要问什么。
06_avatar_middle
最佳答案
0 
ico_lz  楼主| 发表于 2020-7-3 18:40:10 | 显示全部楼层
JLDawson 发表于 2020-7-1 18:57
你去搜索一下无名对象,然后再考虑自己想要问什么。

真不懂,刚学,书没写这个刚开始看类,谢谢你
您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

×【发帖 友情提示】
1、请回复有意义的内容,请勿恶意灌水;
2、纯数字、字母、表情等无意义的内容系统将自动删除;
3、若正常回复后帖子被自动删除,为系统误删的情况,请重新回复其他正常内容或等待管理员审核通过后会自动发布;
4、感谢您对VC驿站一如既往的支持,谢谢合作!

关闭

站长提醒上一条 /2 下一条

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号-4 )|网站地图wx_jqr

GMT+8, 2023-9-29 10:49

Powered by CcTry.CoM

© 2009-2021 cctry.com

快速回复 返回顶部 返回列表