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

所属分类: 软件编程 / C 语言 阅读数: 105
收藏 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++实现string与各种类型之间的转换

这个类在头文件中定义, < sstream>库定义了三种类:istringstream、ostringstream和stringstream,分别用来进行流的输入、输出和输入输出操作。另外,每个类都有一个对应的宽字符集版本
收藏 0 赞 0 分享

C++如何通过ostringstream实现任意类型转string

再使用整型转string的时候感觉有点棘手,因为itoa不是标准C里面的,而且即便是有itoa,其他类型转string不是很方便。后来去网上找了一下,发现有一个好方法
收藏 0 赞 0 分享

C/C++指针小结

要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的类型,指针的值或者叫指针所指向的内存区,还有指针本身所占据的内存区
收藏 0 赞 0 分享

C++ 类的静态成员深入解析

在C++中类的静态成员变量和静态成员函数是个容易出错的地方,本文先通过几个例子来总结静态成员变量和成员函数使用规则,再给出一个实例来加深印象
收藏 0 赞 0 分享

C++类的静态成员初始化详细讲解

通常静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域操作符来指出静态成员所属的类.但如果静态成员是整型或是枚举型const,则可以在类声明中初始化
收藏 0 赞 0 分享

C++类静态成员与类静态成员函数详解

静态成员不可在类体内进行赋值,因为它是被所有该类的对象所共享的。你在一个对象里给它赋值,其他对象里的该成员也会发生变化。为了避免混乱,所以不可在类体内进行赋值
收藏 0 赞 0 分享

C++中的friend友元函数详细解析

友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类。友元函数的特点是能够访问类中的私有成员的非成员函数。友元函数从语法上看,它与普通函数一样,即在定义上和调用上与普通函数一样
收藏 0 赞 0 分享

static全局变量与普通的全局变量的区别详细解析

以下是对static全局变量与普通的全局变量的区别进行了详细的分析介绍,需要的朋友可以过来参考下,希望对大家有所帮助
收藏 0 赞 0 分享

C++ explicit关键字的应用方法详细讲解

C++ explicit关键字用来修饰类的构造函数,表明该构造函数是显式的,既然有"显式"那么必然就有"隐式",那么什么是显示而什么又是隐式的呢?下面就让我们一起来看看这方面的知识吧
收藏 0 赞 0 分享

教你5分钟轻松搞定内存字节对齐

随便google一下,人家就可以跟你解释的,一大堆的道理,我们没怎么多时间,讨论为何要对齐.直入主题,怎么判断内存对齐规则,sizeof的结果怎么来的,请牢记以下3条原则
收藏 0 赞 0 分享
查看更多