C++ 中类的构造函数理解(二)

C++ 中类的构造函数理解(二)

写在前面

上次的笔记中简要的探索了一下C++中类的构造函数的一些特性,这篇笔记将做进一步的探索。主要是复制构造函数的使用。

复制构造函数

复制构造函数也称拷贝构造函数,它只有单个形参,且该形参是对本类类型对象的引用。其作用有以下几点:
1、根据另一个同类型的对象显示或隐式初始化一个对象
2、复制一个对象,将它作为实参传递给一个函数
3、从函数返回时复制一个对象
4、初始化顺序容器中的元素
5、根据元素初始化列表初始化数组元素

编译器合成的复制构造函数

如同默认构造函数一样,如果我们没有显示地定义复制构造函数,编译器将为我们合成一个复制构造函数。合成复制构造函数将新对象初始化为原对象的副本。编译器对每个数据成员进行注意初始化。合成复制构造函数直接复制内置类型成员的值,对于类类型的成员,则使用该类的复制构造函数进行复制。如果某个类包含数组类型的成员,那么合成复制构造函数将复制数组的每个元素。
测试代码如下:

#include<iostream>
#include<cstdio>

using namespace std;

class myClass{
public:
    myClass(int i1, char c1)//普通构造函数
    {
        a = i1;
        c = c1;
    }

    int a;
    char c;
};

int main()
{
    myClass class1(1, ‘a‘);
    myClass class2( class1);//调用合成的复制构造函数

    cout<<"class1 is: "<<class1.a<<" "<<class1.c<<endl;
    cout<<"class2 is: "<<class2.a<<" "<<class2.c<<endl;

    system("pause");
    return 0;
}

运行结果如下:

class1中的成员都被复制到了class2中。合成复制构造函数使用的是浅拷贝的策略。也就是说,如果class1中有指针类型的成员,那么使用合成的复制构造函数时,class2中对应的那个指针与class1中的指针指向的是同一片地址。

自定义的复制构造函数

自己定义复制构造函数时,可将复制构造函数的参数设置为类类型的引用,通常用const修饰参数。尽管也可以接受非const引用的复制构造函数。
测试代码如下:

#include<iostream>
#include<cstdio>

using namespace std;

class myClass{
public:
    myClass(int i1, char c1)//普通构造函数
    {
        a = i1;
        c = c1;
    }

    myClass( const myClass& myclass)//复制构造函数
    {

    }

    int a;
    char c;
};

int main()
{
    myClass class1(1, ‘a‘);
    myClass class2( class1);//调用自定义的复制构造函数

    cout<<"class1 is: "<<class1.a<<" "<<class1.c<<endl;
    cout<<"class2 is: "<<class2.a<<" "<<class2.c<<endl;

    system("pause");
    return 0;
}

上述代码自定义了拷贝构造函数,尽管自定义的复制构造函数函数体为空,但这时系统不再合成复制构造函数,而是调用用户自定义的,此时的运行结果如下:

由于自定义复制构造函数函数体为空,因此没有完成复制。
修改复制构造函如下:

    myClass( const myClass& myclass)
    {
        this->a = myclass.a;
        this->c = myclass.c;
    }

我们可以让自定义的复制构造函数在复制时采用深拷贝的方式。此外,当没有对当前的类重载运行符”=“时,下面这句话也是调用复制构造函数:

    myClass class3 = class1;

总结

这篇笔记写得有点充满,之后有时间需要进一步完善。

时间: 2024-07-30 19:53:25

C++ 中类的构造函数理解(二)的相关文章

spring深入理解二(关于容器工作源码)

spring基本工作原理如下: 1.查找bean配置文件 2.加载bean配置文件并解析生成中间表示BeanDefinition 3.注册beanDefinition 4.如果是单例或lazy-init=false,则直接生成bean spring将 1.查找bean配置文件 2.加载bean配置文件并解析生成中间表示BeanDefinition 3.注册beanDefinition 这三部分开,可以提供更多的定制给用户. spring将配置文件之类的文件资源抽象成一个Resource,封装了g

拷贝构造函数(二)——深拷贝与浅拷贝

拷贝构造函数(一)--哲学三连:http://www.cnblogs.com/tenjl-exv/p/8017814.html 拷贝构造函数(二)--深拷贝与浅拷贝:http://www.cnblogs.com/tenjl-exv/p/8017909.html 拷贝构造函数(三)--重载赋值运算符:http://www.cnblogs.com/tenjl-exv/p/8017983.html

vue-cli 目录理解二

|-- build // webpack配置文件 |-- config // 项目打包路径 |-- src // 源码目录 | |-- components // 组件 | |-- App.vue // 页面入口文件 | |-- main.js // 程序入口文件,加载各种公共组件 |-- .babelrc // ES6语法编译配置 |-- .editorconfig // 代码编写规格 |-- .gitignore // 忽略的文件 |-- index.html // 入口html文件 |--

Spring IOC基于源码的理解(二)

一.知识了解 1.Beanfactory和Application,BeanFactory和FactoryBean 内容在Spring基本知识点(一)后半部分可见: 2.BeanDefinition BeanDefinition是IOC容器体系非常重要的核心数据结构,Spring通过BeanDefinition来管理基于Spring的应用中的各种对象以及他们之间的相互依赖关系,实际就是POJO对象在IOC容器中的抽象.在DefaultListableBeanFactory中使用数据结构Concur

【C++学习之路】派生类的构造函数(二)

二.有内嵌对象的派生类 1.一般来说,我们会这样定义构造函数 student( int i, string nam, int pid, string pnam, int sid) : person( i, nam),parent(pid,pnam){ stuid = sid; } person是基类的构造函数,parent是该派生类内嵌的person子对象   2.具体例子 1 #include <iostream> 2 using namespace std; 3 class A 4 { 5

原型,原型对象,原型链,构造函数,继承(二)

1.prototype(原型对象)有一个属性叫做constructor,constructor默认指向prototype(原型对象)所在的构造函数 2.constructor属性是定义在prototype上的,那就意味着可以被实例对象所继承 3.可以使用hasOwnProperty 方法来验证一个属性是自己的还是继承过来的 4.constructor的作用: 作用一:分辨原型对象到底属于哪个构造函数 instanceof() 作用二:可以从一个实例对象创建另一个实例对象 var Fun = fu

GBDT理解二三事

一.要理解GBDT当然要从GB(Gradient Boosting)和DT(Decision Tree)两个角度来理解了: 二.GB其实是一种理念,他并不是这一个具体的算法,意思是说沿着梯度方向,构造一系列的弱分类器函数,并以一定权重组合起来,形成最终决策的强分类器:注意,这里的梯度下降法是在函数空间中通过梯度下降法寻找使得LOSS最小的一个函数,区别于传统的梯度下降法选择一个方向:那么问题就来了,对函数求导?这也太难了吧.所以就有了一个近似的方法,这个方法的前提是我们认为在训练集上使得LOSS

c++类构造函数理解(转载)

记录一下我对C++类构造函数的理解. 首先,构造函数分成两种,默认构造函数和非默认构造函数(好吧,就这么叫它). 默认构造函数只能有一个,如果没有自定义构造函数,那么编译器将自动生成一个默认构造函数,当然这个构造函数不会做任何事情.如果程序定义了构造函数(包括默认和非默认),编译器都不再自动提供默认构造函数. 如class C, 对应自动生成的默认构造函数为C() { }; 程序员可以自定义默认构造函数,而且只能定义一个默认构造函数.如定义class A. Class A { public: /

理解二维傅里叶变换

图像傅里叶变换的物理意义 图像的频率是表征图像中灰度变化剧烈程度的指标,是灰度在平面空间上的梯度.如:大面积的沙漠在图像中是一片灰度变化缓慢的区域,对应的频率值很低:而对于地表属性变换剧烈的边缘区域在图像中是一片灰度变化剧烈的区域,对应的频率值较高.傅里叶变换在实际中有非常明显的物理意义,设f是一个能量有限的模拟信号,则其傅里叶变换就表示f的频谱.从纯粹的数学意义上看,傅里叶变换是将一个函数转换为一系列周期函数来处理的.从物理效果看,傅里叶变换是将图像从空间域转换到频率域,其逆变换是将图像从频率