博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++中对象的赋值与复制操作详细解析
阅读量:4225 次
发布时间:2019-05-26

本文共 3338 字,大约阅读时间需要 11 分钟。

对象的赋值

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

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

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

对象赋值的一般形式:

对象名1=对象名2;

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

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

代码如下:
#include<iostream>
#include<string>
using namespace std;
class Student
{
 public:
  Student(int nu=0,string na="NULL",int=0);//构造函数
  void show();
 private:
  int num;
  string name;
  int score; 
};
Student::Student(int nu,string na,int sc)
{
 num=nu;
 name=na;
 score=sc; 
}
void Student::show()
{
 cout<<"date:"<<endl;
 cout<<"num:"<<num<<"\tname:"<<name<<"\tscore:"<<score<<endl;
}
int main()
{
 Student s1(1,"qianshou",99);
 s1.show();
 Student s2;
 s2=s1;
 s2.show();
 return 0;
}

运行界面:


说明:

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

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

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

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

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

类名 对象2(对象1)

用对象1复制出对象2.

代码如下:
Student s2(s1);  

可以看到:它与前面介绍的定义对象的方式类似,但是括号中给出的参数不是一般的变来那个,而是对象。

在建立一个新对象时,调用一个特殊的构造函数——复制构造函数。

这个函数是这样的

代码如下:
    Student::Student(const Student &b)  
    {  
        num=b.num;  
        name=b.name;  
        score=b.score;  
    }  

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

对于语句

代码如下:
Student s2(s1);  

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

C++还提供另外一种方便用户的复制形式,用赋值号代替括号

其一般形式是:
类名    对象名1        =        对象名2;

代码如下:
Student s2=s1;

还可以在一个语句中进行多个对象的赋值。

代码如下:
Student    s2=s1,s3=s2,s4=s3;  

对象的复制和赋值的区别
对象的赋值是对一个已经存在的对象赋值,因此必须先定义被赋值的对象,才能进行赋值。而对象的复制则是一个从无到有地建立一个新的对象,并使它与一个已有的对象完全相同(包括对象的结构和成员的值)

代码如下:
    #include<iostream>  
    #include<string>  
    using namespace std;  
    class Student  
    {  
        public:  
            Student(int nu=0,string na="NULL",int=0);//构造函数  
            void show();  
            void reset();   
        private:  
            int num;  
            string name;  
            int score;   
    };  
    Student::Student(int nu,string na,int sc)  
    {  
        num=nu;  
        name=na;  
        score=sc;     
    }  
    void Student::reset()  
    {  
        num=0;  
        name="reset";  
        score=0;  
    }  
    void Student::show()  
    {  
        cout<<"date:"<<endl;  
        cout<<"num:"<<num<<"\tname:"<<name<<"\tscore:"<<score<<endl;  
    }  
    int main()  
    {  
        Student s1(1,"qianshou",99);//实例化一个对象s1   
        Student s2;//声明一个对象s2  
        s2=s1;//进行对象的赋值,将对象s1的值赋给s2   
        s2.show();  
        Student s3(s2);// 进行对象的复制操作   
        s3.show();  
        s3.reset();//s3中的数据成员发生了改变   
        Student s4=s3;//将改变之后的s3复制为s4  
        s4.show();   
        return 0;  
    }  

运行结果:

需要说明的是,赋值构造函数和复制构造函数的调用都是由系统自动完成的。程序员可以自己定义复制构造函数,如果没有定义构造函数,则编译系统会自动提供一个默认的够函数,其作用只是简单的复制类中的数据成员。

我们可以自定义一个复制构造函数,以便查看效果:

代码如下:
    #include<iostream>  
    #include<string>  
    using namespace std;  
    class Student  
    {  
        public:  
            Student(int nu=0,string na="NULL",int=0);//构造函数  
            Student(const Student &s);  
            void show();  
            void reset();   
        private:  
            int num;  
            string name;  
            int score;   
    };  
    Student::Student(int nu,string na,int sc)  
    {  
        num=nu;  
        name=na;  
        score=sc;     
    }  
    Student::Student(const Student &s)  
    {  
        num=s.num;  
        name=s.name;  
        score=s.score;  
        cout<<"复制构造函数执行完毕"<<endl;  
    }  
    void Student::reset()  
    {  
        num=0;  
        name="reset";  
        score=0;  
    }  
    void Student::show()  
    {  
        cout<<"date:"<<endl;  
        cout<<"num:"<<num<<"\tname:"<<name<<"\tscore:"<<score<<endl;  
    }  
    int main()  
    {  
        Student s1(1,"qianshou",99);//实例化一个对象s1   
        Student s2;//声明一个对象s2  
        s2=s1;//进行对象的赋值,将对象s1的值赋给s2   
        s2.show();  
        Student s3(s2);// 进行对象的复制操作   
        s3.show();  
        s3.reset();//s3中的数据成员发生了改变   
        Student s4=s3;//将改变之后的s3复制为s4  
        s4.show();   
        return 0;  
    }  

转载地址:http://edkqi.baihongyu.com/

你可能感兴趣的文章
Web前端学习笔记——JavaScript之面向对象游戏案例:贪吃蛇
查看>>
不做单元测试?小心得不偿失!嵌入式系统单元测试工具,自动生成测试用例
查看>>
一种实用的联网汽车无线攻击方法及车载安全协议
查看>>
光靠欺骗检测是不够的:对抗多目标跟踪的攻击
查看>>
基于微区块链的V2X地理动态入侵检测
查看>>
面向V2C场景的ADAS数字孪生模型构建方法
查看>>
Comma2k19数据集使用
查看>>
面向自动驾驶车辆验证的抽象仿真场景生成
查看>>
一种应用于GPS反欺骗的基于MLE的RAIM改进方法
查看>>
自动驾驶汽车GPS系统数字孪生建模(一)
查看>>
自动驾驶汽车GPS系统数字孪生建模(二)
查看>>
CUDA 学习(五)、线程块
查看>>
CUDA 学习(八)、线程块调度
查看>>
CUDA 学习(九)、CUDA 内存
查看>>
CUDA 学习(十一)、共享内存
查看>>
游戏感:虚拟感觉的游戏设计师指南——第十四章 生化尖兵
查看>>
游戏感:虚拟感觉的游戏设计师指南——第十五章 超级马里奥64
查看>>
游戏感:虚拟感觉的游戏设计师指南——第十七章 游戏感的原理
查看>>
游戏感:虚拟感觉的游戏设计师指南——第十八章 我想做的游戏
查看>>
游戏设计的艺术:一本透镜的书——第十章 某些元素是游戏机制
查看>>