C++中对象的赋值与复制操作详细解析

所属分类: 软件编程 / C 语言 阅读数: 80
收藏 0 赞 0 分享

对象的赋值

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

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

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

对象名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; 
    } 

更多精彩内容其他人还在看

C++中四种对象生存期和作用域以及static的用法总结分析

以下是对C++中四种对象生存期和作用域以及static的用法进行了详细的介绍,需要的朋友可以过来参考下
收藏 0 赞 0 分享

C++嵌套类与局部类详细解析

从作用域的角度看,嵌套类被隐藏在外围类之中,该类名只能在外围类中使用。如果在外围类之外的作用域使用该类名时,需要加名字限定
收藏 0 赞 0 分享

C++空类详解

以下是对C++中的空类进行了详细的介绍,需要的朋友可以过来参考下
收藏 0 赞 0 分享

C++之友元:友元函数和友元类详解

友元是一种允许非类成员函数访问类的非公有成员的一种机制。可以把一个函数指定为类的友元,也可以把整个类指定为另一个类的友元
收藏 0 赞 0 分享

C++中返回指向函数的指针示例

int (*ff(int)) (int *,int);表示:ff(int)是一个函数,带有一个int型的形参,该函数返回int (*) (int *,int),它是一个指向函数的指针,所指向的函数返回int型并带有两个分别是Int*和int型的形参
收藏 0 赞 0 分享

C数据结构之单链表详细示例分析

以下是对C语言中的单链表进行了详细的分析介绍,需要的朋友可以过来参考下
收藏 0 赞 0 分享

C数据结构之双链表详细示例分析

以下是对c语言中的双链表进行了详细的分析介绍,需要的朋友可以过来参考下
收藏 0 赞 0 分享

浅析如何在c语言中调用Linux脚本

如何在c语言中调用Linux脚本呢?下面小编就为大家详细的介绍一下吧!需要的朋友可以过来参考下
收藏 0 赞 0 分享

深入解析unsigned int 和 int

以下是对unsigned int和int进行了详细的分析介绍,需要的朋友可以过来参考下
收藏 0 赞 0 分享

浅谈C++中的string 类型占几个字节

本篇文章小编并不是为大家讲解string类型的用法,而是讲解我个人比较好奇的问题,就是string 类型占几个字节
收藏 0 赞 0 分享
查看更多