C++笔记-面向对象(OOP)编程基础(概念、类中的封装;类的构造和析构)--赋值构造函数四种应用场景 深copy和浅copy 类的三种构造函数的调用规则研究(3-1)

目录

赋值构造函数四种应用场景

第一个应用场景

第二个应用场景

第三个应用场景

第四个应用场景 匿名对象

深copy和浅copy

类的三种构造函数的调用规则研究



赋值构造函数四种应用场景

注:对象初始化操作 和 =等号操作 是两个不同的概念

类定义

class Student {

    private:
        int a;

    public:
        Student();

        Student(int a);

        Student(const Student &student);

        ~Student();

};

类实现

#include "Student.h"
#include "iostream"

using namespace std;

Student::Student() {
    cout << "我是构造函数,自动被调用" << endl;
}

Student::Student(int a) {
    this->a = a;
    cout << "我是构造函数,自动被调用" << endl;
}

Student::Student(const Student &student) {
    cout << "我是构造函数,我是通过另外一个对象student,来初始化自己" << endl;
}

Student::~Student() {
    cout << "我是析构函数,自动被调用" << endl;
}

第一个应用场景

//单独搭建一个舞台
//对象初始化操作 和 =等号操作 是两个不同的概念
void scence1()
{
    Student a1; //变量定义

    //赋值构造函数的第一个应用场景
    //我用对象1 初始化 对象2
    Student a2 = a1; //定义变量并初始化

    a2 = a1; //用a1来=号给a2 编译器给我们提供的浅copy
}

结果

我是构造函数,自动被调用
我是构造函数,我是通过另外一个对象student,来初始化自己
我是析构函数,自动被调用
我是析构函数,自动被调用

第二个应用场景

//单独搭建一个舞台
//对象初始化操作 和 =等号操作 是两个不同的概念
void scence2()
{
    Student a1(10); //变量定义

    //赋值构造函数的第一个应用场景
    //我用对象1 初始化 对象2
    Student a2(a1); //定义变量并初始化

    a2 = a1; //用a1来=号给a2 编译器给我们提供的浅copy
}

结果

我是构造函数,自动被调用
我是构造函数,我是通过另外一个对象student,来初始化自己
我是析构函数,自动被调用
我是析构函数,自动被调用

第三个应用场景

Student scense3() {
    Student s(1);
    return s;
}

int main() {

    Student student;
    student = scense3();
    cout << "student" << endl;

    return 0;
}

第四个应用场景 匿名对象

对象初始化操作 和 =等号操作 是两个不同的概念

void mainobjplay()
{  
	//Location B;
	//B = g();

	Location B = g();
	//如果返回的匿名对象,来初始化另外一个同类型的类对象,那么匿名对象会直接转成新的对象。。。
	//匿名对象的去和留,关键看,返回时如何接过来。
	cout<<"测试测试"<<endl;
}

说明

如果返回的匿名对象,来初始化另外一个同类型的类对象,那么匿名对象会直接转成新的对象

匿名对象的去和留,关键看,返回时如何接过来

深copy和浅copy

例子


class Name {
    private:
        int size;
        char *name;
    public:
        Name(char *name) {
            size = strlen(name);
            this->name = (char *)malloc(size + 1);
            strcpy(this->name, name);
            cout << "构造函数..." << endl;
        }
        Name(Name &obj) {
            size = obj.size;
            this->name = (char *) malloc(obj.size + 1);
            cout << "构造函数..." << endl;
        }
        ~Name() {
            if(name != NULL) {
                free(name);
                name = NULL;
                size = 0;
            }
            cout << "析构函数..." << endl;
        }
};

int main() {

    Name a("test");

    //浅copy 没有编写该构造函数时,自动调用编译器提供的浅拷贝方法,这种情况两个指针指向同一个地址,第一个对象释放指针,第二个对象释放就会异常
    //深copy 编写该构造函数时,两个指针指向不同地址,各自释放就不会有异常
    Name b(a);

    return 0;
}

结果 上述例子

浅copy 没有编写该构造函数时,自动调用编译器提供的浅拷贝方法,这种情况两个指针指向同一个地址,第一个对象释放指针,第二个对象释放就会异常

深copy 编写该构造函数时,两个指针指向不同地址,各自释放就不会有异常

类的三种构造函数的调用规则研究

1 当类中没有定义任何一个构造函数时,c++编译器会提供无参构造函数和拷贝构造函数

2 当类中定义了任意的非拷贝构造函数(无参、有参),c++编译器不会提供无参构造函数

3 当类中定义了拷贝构造函数时,c++编译器不会提供无参数构造函数

4 默认拷贝构造函数成员变量简单赋值

总结:只要你写了构造函数,那么你必须用。

构造函数是C++中用于初始化对象状态的特殊函数

构造函数在对象创建时自动被调用

构造函数和普通成员函数都遵循重载规则

拷贝构造函数是对象正确初始化的重要保证必要的时候,必须手工编写拷贝构造函数

构造函数和析构函数调用顺序总结

构造函数与析构函数的调用顺序

当类中有成员变量是其它类的对象时

首先调用成员变量的构造函数

调用顺序与声明顺序相同

之后调用自身类的构造函数

析构函数的调用秩序与对应的构造函数调用秩序相反

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值