类和对象(上)

本文详细介绍了C++中类的概念、对象的创建、构造函数(包括默认构造函数和重载)、析构函数以及拷贝构造函数的作用和使用,强调了内存管理和深浅拷贝的重要性。
摘要由CSDN通过智能技术生成

​​​​​​


目录

1.类的概念

2.对象的概念

3.构造函数

4.析构函数

5.拷贝构造函数


众所周知,C++是一门面对对象的语言,而面对对象的语言具有三大特性(封装   继承   多态)

C++中的对象与C语言中的结构体具有极大的相似性(可以理解成对象是结构体的升级版)

     

上面是一个简单的类的定义

1. 类定义后会加一个   这个与结构体一致

2.一个类可以定义多个对象,每一个对象都是一个变量

3.类和结构体一样,都是自定义类型,计算内存时,要考虑内存对齐

4.类里面可以有  变量  和   函数

5.类的访问 依然用 .   或   ->  访问

类的定义  可以分为两种方式   struct定义     class定义

区别:

struct 定义的变量和函数均是 public(公共属性)

class 分为 public  private   protected

举个例子:

  struct 默然是公共属性  class默然是私有属性

对象的概念:

对象就是类的实例化

   

注意:类里面是可以嵌套的

注意:private 后面接的是变量的声明,而不是定义    B s是变量的定义

下面讲解构造函数

1.函数名与类名相同

2.无返回值

3.对象实例化时,编译器自动调用对应的构造函数(这一点特别重要)

4.构造函数可以重载(要注意是否会产生调用歧义)

举个例子:

第一点:当我们没有写构造函数,编译器会自动生成一个构造函数,这个构造函数对内置类型(包括int double char float 指针等)不处理,对自定义类型(结构体和类)调用他自己的构造函数

此时你会发现内置类型再去调用它的构造函数,最终还是对内置类型进行初始化

第二点:当我们在定义对象时,没有传参,此时他会调用它的默认构造函数

补充:默认构造函数有三种   无参构造   全缺省构造   编译器默认生成的构造函数(当我们写了构造函数,编译器不会生成了)

举个例子:

  A s 代表无参构造 ,则调用默认构造函数,此时由于已经有A(.....) 编译器不会自动生成 , 则没有默认构造函数

还有一种初始化的方法

#include <iostream>
using namespace std;
class A
{
public:

private:
    int _a = 1;
    int _b = 2;
    int _c = 3;

};
int main()
{
    A s;
    return 0;
}

这段带码的含义是由于没有写构造函数,编译器自动生成,但此时由于我写了int _a = 1.......

相当于这个代码 这两个代码等效

析构函数:(相当于destory, 销毁对象的空间)

析构函数主要是对从堆上拿来的空间释放,防止内存泄漏

格式:~ + 类型名(注意析构函数没有返回值)

注意析构函数不能函数重载,一个类只能有一个析构函数

当对象里面有自定义类型时,回去调用它的析构函数,对于内置类型,就调用自己的析构函数,如果没有,就不做处理

#include <iostream>
using namespace std;
class B
{
public:
    ~B()
    {
        cout << 1 << endl;
    }
};
class A
{
public:
    A( int a = 1 , int b = 2 , int c = 3 )
    {
        _arr = (int*)malloc(sizeof(int)*10);
        _a = a;
        _b = b;
        _c = c;
    }
    ~A()
    {
        free(_arr);
        _a = 0;
        _b = 0;
        _c = 0;
    }
private:
    class B t;
    int* _arr;
    int _a ;
    int _b ;
    int _c ;
};
int main()
{
    A s;
    return 0;
}

下面的代码就会打印出来1

拷贝构造函数:

用一个现有的对象去初始化未知的对象


#include <iostream>
using namespace std;
class A
{
public:
    A()
    {
        _a = 1;
        _b = 2;
    }
    A(const A& t)拷贝构造函数用的是&引用
    {
        this->_a = t._a;
        this->_b = t._b;
    }
private:
    int _a;
    int _b;
};
int main()
{
    A s;
    A t(s);
    return 0;
}

如果我们没写拷贝构造函数,那么编译器会自动生成一个拷贝构造函数,请注意这一拷贝构造函数是浅拷贝(就是通过字节上面存储的数值,一个一个字节的拷贝)

这时会出现一个Bug

#include <iostream>

using namespace std;
class A
{
public:
    A()
    {
        _arr = (int*)malloc(sizeof(int)*100);
        _a = 1;
        _b = 2;
    }
    ~A()
    {
        free(this->_arr);
    }
private:
    int* _arr;
    int _a;
    int _b;
};
int main()
{
    A s;
    A t(s);
    return 0;
}

这个代码会崩溃

原因:

s的指针与t的指针指向同一块区域

当free时,程序崩溃

此时,要进行深拷贝

#include <iostream>
using namespace std;
class A
{
public:
    A()
    {
        _arr = (int*)malloc(sizeof(int)*100);
        _a = 1;
        _b = 2;
    }
    A( const A& t )
    {
        int* temp = (int*)malloc(sizeof(int)*10);
        if( !temp )
        exit(1);
        this->_arr = temp;
        this->_a = t._a;
        this->_b = t._b;
    }
    ~A()
    {
        free(this->_arr);
    }
private:
    int* _arr;
    int _a;
    int _b;
};
int main()
{
    A s;
    A t(s);
    return 0;
}

结论:当要malloc空间时,要进行深拷贝

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值