热门标签 | HotTags
当前位置:  开发笔记 > IOS > 正文

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

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

对象的赋值

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

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

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

对象名1=对象名2;

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

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

代码如下:

#include
#include
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:"< cout<<"num:"<}
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 
    #include 
    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:"<        cout<<"num:"<    } 
    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 
    #include 
    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<<"复制构造函数执行完毕"<    } 
    void Student::reset() 
    { 
        num=0; 
        name="reset"; 
        score=0; 
    } 
    void Student::show() 
    { 
        cout<<"date:"<        cout<<"num:"<    } 
    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; 
    } 


推荐阅读
  • 并发编程:深入理解设计原理与优化
    本文探讨了并发编程中的关键设计原则,特别是Java内存模型(JMM)的happens-before规则及其对多线程编程的影响。文章详细介绍了DCL双重检查锁定模式的问题及解决方案,并总结了不同处理器和内存模型之间的关系,旨在为程序员提供更深入的理解和最佳实践。 ... [详细]
  • 本章将深入探讨移动 UI 设计的核心原则,帮助开发者构建简洁、高效且用户友好的界面。通过学习设计规则和用户体验优化技巧,您将能够创建出既美观又实用的移动应用。 ... [详细]
  • Linux 系统启动故障排除指南:MBR 和 GRUB 问题
    本文详细介绍了 Linux 系统启动过程中常见的 MBR 扇区和 GRUB 引导程序故障及其解决方案,涵盖从备份、模拟故障到恢复的具体步骤。 ... [详细]
  • 理解存储器的层次结构有助于程序员优化程序性能,通过合理安排数据在不同层级的存储位置,提升CPU的数据访问速度。本文详细探讨了静态随机访问存储器(SRAM)和动态随机访问存储器(DRAM)的工作原理及其应用场景,并介绍了存储器模块中的数据存取过程及局部性原理。 ... [详细]
  • 自学编程与计算机专业背景者的差异分析
    本文探讨了自学编程者和计算机专业毕业生在技能、知识结构及职业发展上的不同之处,结合实际案例分析两者的优势与劣势。 ... [详细]
  • SQLite 动态创建多个表的需求在网络上有不少讨论,但很少有详细的解决方案。本文将介绍如何在 Qt 环境中使用 QString 类轻松实现 SQLite 表的动态创建,并提供详细的步骤和示例代码。 ... [详细]
  • MySQL 数据库迁移指南:从本地到远程及磁盘间迁移
    本文详细介绍了如何在不同场景下进行 MySQL 数据库的迁移,包括从一个硬盘迁移到另一个硬盘、从一台计算机迁移到另一台计算机,以及解决迁移过程中可能遇到的问题。 ... [详细]
  • 阅读本文大约需要3分钟。微信8.0版本的发布带来了许多令人振奋的新功能,如烟花特效和改进的悬浮窗,引发了用户的热烈反响。 ... [详细]
  • 深入理解Java泛型:JDK 5的新特性
    本文详细介绍了Java泛型的概念及其在JDK 5中的应用,通过具体代码示例解释了泛型的引入、作用和优势。同时,探讨了泛型类、泛型方法和泛型接口的实现,并深入讲解了通配符的使用。 ... [详细]
  • 作为一名程序员,从大学步入职场后,常常感受到一种难以言喻的空虚感。这种感觉或许源于对生活的不满、职业发展的瓶颈,或是日常琐事带来的压力。本文将深入探讨这种复杂的情感,并尝试寻找解决之道。 ... [详细]
  • 深入解析:阿里实战 SpringCloud 微服务架构与应用
    本文将详细介绍 SpringCloud 在微服务架构中的应用,涵盖入门、实战和案例分析。通过丰富的代码示例和实际项目经验,帮助读者全面掌握 SpringCloud 的核心技术和最佳实践。 ... [详细]
  • 本文深入探讨了C++对象模型中的一些细节问题,特别是虚拟继承和析构函数的处理。通过具体代码示例和详细分析,揭示了书中某些观点的不足之处,并提供了更合理的解释。 ... [详细]
  • 随着网络安全威胁的不断演变,电子邮件系统成为攻击者频繁利用的目标。本文详细探讨了电子邮件系统中的常见漏洞及其潜在风险,并提供了专业的防护建议。 ... [详细]
  • 微软Exchange服务器遭遇2022年版“千年虫”漏洞
    微软Exchange服务器在新年伊始遭遇了一个类似于‘千年虫’的日期处理漏洞,导致邮件传输受阻。该问题主要影响配置了FIP-FS恶意软件引擎的Exchange 2016和2019版本。 ... [详细]
  • 探讨如何真正掌握Java EE,包括所需技能、工具和实践经验。资深软件教学总监李刚分享了对毕业生简历中常见问题的看法,并提供了详尽的标准。 ... [详细]
author-avatar
k3as0n_701
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有