对象的赋值

如果对一个类定义了两个或多个对象,则这些同类的对象之间可以互相赋值,或者说,一个对象的值可以赋给另一个同类的对象。这里所指的对象的值是指对象中所有数据成员的值。

对象之间的赋值也是通过赋值运算符“=”进行的。本来赋值运算符“=”只能用来对单个的变量赋值,现在被扩展为两个同类对象之间的赋值,这是通过对赋值运算符的重载实现的。

实际上这个过程是通过成员复制来实现的,即将一个对象的成员值一一复制给另外一个对象的成员。

对象赋值的一般形式:

对象名1=对象名2;

注意,对象1和对象2必须是属于同一个类

=========示例代码1.1===============

  1. #include<iostream>
  2. #include<string>
  3. using namespace std;
  4. class Student
  5. {
  6. public:
  7. Student(int nu=0,string na="NULL",int=0);//构造函数
  8. void show();
  9. private:
  10. int num;
  11. string name;
  12. int score;
  13. };
  14. Student::Student(int nu,string na,int sc)
  15. {
  16. num=nu;
  17. name=na;
  18. score=sc;
  19. }
  20. void Student::show()
  21. {
  22. cout<<"date:"<<endl;
  23. cout<<"num:"<<num<<"\tname:"<<name<<"\tscore:"<<score<<endl;
  24. }
  25. int main()
  26. {
  27. Student s1(1,"qianshou",99);
  28. s1.show();
  29. Student s2;
  30. s2=s1;
  31. s2.show();
  32. return 0;
  33. }

运行界面:

说明:

(1)对象的赋值值对其中的数据成员赋值,而不对成员函数赋值。

数据成员是占存储空间的,不同的对象的数据成员占有不同的存储空间,赋值过程是将一个对象的数据成员在存储空间的状态复制给另一对象的数据成员的存储空间。

而不同对象的成员函数是同一个函数代码段,既不需要也没法向它们赋值。

(2)类的数据成员中,不能包括动态分配的数据。

对象的复制

有时我们需要用到多个完全相同的对象,并进行相同的初始化。或者有时候,我们需要将对象在某一瞬间的状态保留下来。
为了处理这种情况,C++提供了对象的复制机制,用一个以后的对象快速的复制出多个完全相同的对象。
其一般形式为

类名 对象2(对象1)

用对象1复制出对象2.
  1. Student s2(s1);

可以看到:它与前面介绍的定义对象的方式类似,但是括号中给出的参数不是一般的变来那个,而是对象。
在建立一个新对象时,调用一个特殊的构造函数——复制构造函数。

这个函数是这样的
  1. Student::Student(const Student &b)
  2. {
  3. num=b.num;
  4. name=b.name;
  5. score=b.score;
  6. }

复制构造函数也是构造函数,但它只有一个参数,这个参数时本类的对象,而且采用对象的引用形式(一般约定加const声明,使参数值不能改变,以免在调用函数时因不慎而使对象值被修改)。此复制构造函数的作用就是将实参对象的各数据成员的值一一赋给新的对象中的成员的值。

对于语句
  1. Student s2(s1);

这实际上也是建立对象的语句,建立一个新对象s2。由于在括号内给定的实参是对象,编译系统就调用复制构造函数,实参s1的值传给形参b(b是s1的引用)。


C++还提供另外一种方便用户的复制形式,用赋值号代替括号
其一般形式是:
类名    对象名1        =        对象名2;
  1. Student s2=s1;

还可以在一个语句中进行多个对象的赋值。
  1. Student s2=s1,s3=s2,s4=s3;

对象的复制和赋值的区别

对象的赋值是对一个已经存在的对象赋值,因此必须先定义被赋值的对象,才能进行赋值。而对象的复制则是一个从无到有地建立一个新的对象,并使它与一个已有的对象完全相同(包括对象的结构和成员的值)
  1. #include<iostream>
  2. #include<string>
  3. using namespace std;
  4. class Student
  5. {
  6. public:
  7. Student(int nu=0,string na="NULL",int=0);//构造函数
  8. void show();
  9. void reset();
  10. private:
  11. int num;
  12. string name;
  13. int score;
  14. };
  15. Student::Student(int nu,string na,int sc)
  16. {
  17. num=nu;
  18. name=na;
  19. score=sc;
  20. }
  21. void Student::reset()
  22. {
  23. num=0;
  24. name="reset";
  25. score=0;
  26. }
  27. void Student::show()
  28. {
  29. cout<<"date:"<<endl;
  30. cout<<"num:"<<num<<"\tname:"<<name<<"\tscore:"<<score<<endl;
  31. }
  32. int main()
  33. {
  34. Student s1(1,"qianshou",99);//实例化一个对象s1
  35. Student s2;//声明一个对象s2
  36. s2=s1;//进行对象的赋值,将对象s1的值赋给s2
  37. s2.show();
  38. Student s3(s2);// 进行对象的复制操作
  39. s3.show();
  40. s3.reset();//s3中的数据成员发生了改变
  41. Student s4=s3;//将改变之后的s3复制为s4
  42. s4.show();
  43. return 0;
  44. }

运行结果:



需要说明的是,赋值构造函数和复制构造函数的调用都是由系统自动完成的。程序员可以自己定义复制构造函数,如果没有定义构造函数,则编译系统会自动提供一个默认的够函数,其作用只是简单的复制类中的数据成员。
我们可以自定义一个复制构造函数,以便查看效果:
  1. #include<iostream>
  2. #include<string>
  3. using namespace std;
  4. class Student
  5. {
  6. public:
  7. Student(int nu=0,string na="NULL",int=0);//构造函数
  8. Student(const Student &s);
  9. void show();
  10. void reset();
  11. private:
  12. int num;
  13. string name;
  14. int score;
  15. };
  16. Student::Student(int nu,string na,int sc)
  17. {
  18. num=nu;
  19. name=na;
  20. score=sc;
  21. }
  22. Student::Student(const Student &s)
  23. {
  24. num=s.num;
  25. name=s.name;
  26. score=s.score;
  27. cout<<"复制构造函数执行完毕"<<endl;
  28. }
  29. void Student::reset()
  30. {
  31. num=0;
  32. name="reset";
  33. score=0;
  34. }
  35. void Student::show()
  36. {
  37. cout<<"date:"<<endl;
  38. cout<<"num:"<<num<<"\tname:"<<name<<"\tscore:"<<score<<endl;
  39. }
  40. int main()
  41. {
  42. Student s1(1,"qianshou",99);//实例化一个对象s1
  43. Student s2;//声明一个对象s2
  44. s2=s1;//进行对象的赋值,将对象s1的值赋给s2
  45. s2.show();
  46. Student s3(s2);// 进行对象的复制操作
  47. s3.show();
  48. s3.reset();//s3中的数据成员发生了改变
  49. Student s4=s3;//将改变之后的s3复制为s4
  50. s4.show();
  51. return 0;
  52. }





C++中的对象的赋值和复制的更多相关文章

  1. 不可或缺 Windows Native (19) - C++: 对象的动态创建和释放, 对象的赋值和复制, 静态属性和静态函数, 类模板

    [源码下载] 不可或缺 Windows Native (19) - C++: 对象的动态创建和释放, 对象的赋值和复制, 静态属性和静态函数, 类模板 作者:webabcd 介绍不可或缺 Window ...

  2. C++:对象的赋值和复制

    3.6.1 对象赋值语句 如同基本类型赋值语句一样,同类型的对象之间也可以进行赋值,即一个对象的值可以赋给另一个对象.这里所指的对象的赋值是指对其中的数据成员赋值,而不对成员函数赋值.例如:A和B是同 ...

  3. C++ 对象的赋值和复制 基本的

    对象的赋值 如果对一个类定义了两个或多个对象,则这些对象之间是可以进行赋值,或者说,一个对象的值可以赋值给另一个同类的对象.这里所指的值是指对象中所有数       据的成员的值.对象之间进行赋值是“ ...

  4. C++,对象的 =赋值 以及 复制构造函数赋值

    1. C++默认实现了 = 号赋值:operator=只要将一个对象的内容的内容逐位复制给另外一个对象即可. 2. C++默认实现了复制构造函数:同样,只要将一个对象的内容的内容逐位复制给另外一个对象 ...

  5. python中拷贝对象的区别

    一.赋值.引用 在python中赋值语句总是建立对象的引用值,而不是复制对象.因此,python变量更像是指针,而不是数据存储区域 这点和大多数语音类似吧,比如C++.Java等 1.先看个例子: v ...

  6. java数组对象的浅层复制与深层复制

    实际上,java中数组对象的浅层复制只是复制了对象的引用(参考),而深层复制的才是对象所代表的值.

  7. python中的浅拷贝与赋值不同

    Python中的对象之间赋值时是按引用传递的,如果需要拷贝对象,需要使用标准库中的copy模块. 1. copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象. 2. copy.deep ...

  8. JavaScript 中的对象深度复制(Object Deep Clone)

    JavaScript中并没有直接提供对象复制(Object Clone)的方法. JavaScript中的赋值,其实并不是复制对象,而是类似`c/c++`中的引用(或指针),因此下面的代码中改变对象b ...

  9. 【转】JavaScript中的对象复制(Object Clone)

    JavaScript中并没有直接提供对象复制(Object Clone)的方法.因此下面的代码中改变对象b的时候,也就改变了对象a. a = {k1:1, k2:2, k3:3}; b = a; b. ...

随机推荐

  1. 基本jquery

    <!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...

  2. 每天一个Linux命令(5)rm命令

    rm命令可以删除一个目录中的一个或多个文件或目录,也可以将某个目录及其下属的所有文件及其子目录均删除掉.对于链接文件,只是删除整个链接文件,而原有文件保持不变. 注意:使用rm命令要格外小心.因为一旦 ...

  3. Drools Expression 介绍

    用好Drools 中的表达式是你的规则引擎能否强大的必要条件 http://docs.jboss.org/drools/release/6.1.0.Final/drools-docs/html_sin ...

  4. TYOI Day1 travel:Tree dp【处理重复走边】

    题意: 给你一棵树,n个节点,每条边有长度. 然后有q组询问(u,k),每次问你:从节点u出发,走到某个节点的距离mod k的最大值. 题解: 对于无根树上的dp,一般都是先转成以1为根的有根树,然后 ...

  5. 英语发音规则---Y字母

    英语发音规则---Y字母 一.总结 一句话总结: 1.Y字母在单词最前面读发[j]? yes /jes/ [jɛs] n. 是 yard /jɑːd/ [jɑd] n. 院子 yellow /'jel ...

  6. 用一句SQL取出第 m 条到第 n 条记录的方法

    1 --从Table 表中取出第 m 条到第 n 条的记录:(Not In 版本)2 3 SELECT TOP n-m+1 * 4 FROM Table 5 WHERE (id NOT IN (SEL ...

  7. jQuery向上遍历DOM树之parents(),parent(),closest()之间的区别

    http://www.poluoluo.com/jzxy/201312/253059.html 在这个sprint中,因为要写前端UI,所以用到了jQuery,但是jQuery在向上遍历DOM树的AP ...

  8. Python习题-统计日志中访问次数超过限制的IP

    #1.1分钟之内ip访问次数超过200次的,就给他的ip加入黑名单#需求分析: #1.读日志,1分钟读一次 #2.获取这1分钟之内所有访问的ip #3.判断ip出现的次数,如果出现200次,那么就加入 ...

  9. ATL和vc++中的智能指针(分别是CComPtr和_com_ptr_t)

    一.智能指针的概念 智能指针是一个类,不是指针,智能指针在所包含的指针不再被使用时候会自动释放该所包含指针所占用的系统资源,而不用手动释放. 原理:智能指针封装了包含指针的AddRef()函数和Rel ...

  10. Cassini(卡西尼)投影