IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++中构造与析构函数 -> 正文阅读

[C++知识库]C++中构造与析构函数

一、构造函数

1、构造函数也是函数的一种, 构造函数的主要任务就是初始化类中成员变量

在C++中,通过一个类去创建对象时,那么编译器会完成两个工作:

1)给对象分配一块内存,类似于int? i

2)C++编译器强行调用构造函数,并且为隐式调用

2、构造函数的语法

特点:

  1. 构造函数的函数名必须跟类名
  2. 构造函数无返回值
  3. 当我们创建类对象的时,构造函数会被自动调用,无需我们主动调用

一个类中,可以有多个构造函数,构造函数之间可构成函数重载的关系

无参构造函数

有参构造函数

class Kitty{

public:
     //编译器会默认提供一个无参构造函数,如果手动实现构造函数(无参和有参),则默认就不在提供无参构造函数
    //无参构造函数
    Kitty()
    {
        cout << "Kitty()" << endl;
    }
     Kitty(float weight1 = 0.0)
    {
         cout << "Kitty(float weight = 0.0)" << endl;
         weight = weight1;
    }

     Kitty(string sex1 = "M",float weight1 = 0.0)
    {
          cout << " Kitty(string sex1 = "",float weight1 = 0.0)" << endl;
            weight = weight1;

            sex = sex1;
    }

    Kitty(string sex1 = "M",string color1 = nullptr,float weight1 = 0.0)
    {
            cout << " Kitty(string sex1 = "",string color1 = nullptr,float weight1 = 0.0)" << endl;
            weight = weight1;
            color = color1;
            sex = sex1;
    }

    void printK()
    {
        cout << "weight = " << weight << sex << color << endl;
    }
private:
    float weight;
    string sex;
    string color;
    //const int i;
    //static int i
    //T t;
};
int main()
{
    /*
    main.cpp:41:11: error: call to constructor of 'Kitty' is ambiguous
    main.cpp:11:5: note: candidate constructor
    main.cpp:15:5: note: candidate constructor
    main.cpp:20:5: note: candidate constructor
    main.cpp:25:5: note: candidate constructor
    */
   // Kitty cat;
    Kitty t1("M",2.0); //ok
    t1.printK();
    Kitty t2(2.0); //ok
    t2.printK();
    Kitty t3("W","white",0.2); //ok
    t3.printK();

    return 0;
}

类对象所占内存的分析:

总结:对于构造函数要记住特点,构造函数在创建对象时,会被调用,主要任务用来初始化成员,除此之外,它跟普通 的成员函数 并没有区别,也可以来实现函数调用,条件判断,循环,赋值等操作,但是,不建议在构造函数中,做过多的逻辑操作。从一定程度上,会导致效率降低。

3、创建类对象的方式

在栈上

在堆上

静态存储区

跟普通类型的变量,并无区别

int i; //在栈上 ---- 在左大括号开始,右大括号结束

在C语言中,利用malloc 和 free函数

type* p = (type*)malloc(sizeof(type))

在C++中,也是有一种更好的解决方案:new/delete运算符

type* 指针变量 = new type; //无参构造函数
type* 指针变量 = new type(参数列表);//有参构造函数

  Kitty* pk = new Kitty("W","white",0.2);
  pk->printK();

  delete pk;

  static type i ;

二、拷贝构造函数

类是一种类类型,那么就存在以下这个情况

//定义一个类类型
class Test
{
    public:
        Test(int m_t)
        {
            t = m_t;
        }
  private:
  int t;  
};
使用:
Test t;
// int i = 10;  int j = i;  使用一个变量给另一个声明的变量初始化
Test t1 = t; //如果成立,则表明,确实存在使用一个对象来初始化另一个对象
             //而在创建对象t1时,必须会调用构造函数 --- 拷贝构造函数

拷贝构造函数的原型:?

类名(const 类名& anther)
{
    成员变量 = anther.成员变量
}
系统会提供一个默认的拷贝构造函数,如果一经手动实现,则系统提供的拷贝构造函数
就不复存在,系统默认提供的拷贝构造函数是一个浅拷贝(简单的用一个对象的成员的值
来给另一个对象的成员进行初始化  比如 t = other.t)

深拷贝:手动重新实现拷贝构造函数简单赋值之外的操作,称之为深拷贝

class Test
{
    public:

        Test(int m_t = 0)
        {
            cout << "Test(int m_t = 0)" << endl;
           // t = m_t;

           // t = new int; //ok
            t = (int*)malloc(sizeof(int));

            if(t != NULL)
            {
                 *t = m_t;
            }

        }

        //拷贝构造函数
        Test(const Test& other)
        {
            cout << "Test(const Test& other)" << endl;
           // t = other.t; 简单的赋值操作,浅拷贝
            //重新给指针变量申请堆空间
            t = (int*)malloc(sizeof(int));
            if(t != NULL)
            {
                 *t = *(other.t);
            }
        }
        void printT()
        {
            cout << "t = " << *t << endl;
        }

        //手动实现资源
        void Tfree()
        {
            if(t != NULL)
            {
                free(t);
                t = NULL;
            }
        }

  private:
  int* t;
};
int main()
{
     Test t1(3); //调用有参构造函数
     t1.printT();

     Test t2 = t1; //调用拷贝构造函数
     t2.printT();

     t1.Tfree(); //对象t1释放申请的内存
     t2.Tfree(); //对象t2释放申请的内存  同一块内存被第二次释放内存
                // double free or corruption (fasttop): 0x0000000001337030 *
                //原因在于默认的拷贝是浅拷贝,如果类的成员变量有指针时,拷贝要使用深拷贝
    return 0;
}

三、 析构函数

在C++中,类可以定义一个特殊的成员函数清理对象(变量)所占用的资源,该成员函数叫做析构

函数

规则:

  • 对象销毁时,自动调用,完成销毁后清理工作(不是清理对象本身,而是清理在使用过资源)
  • 无返回值,函数名与类名相同。无参,不可以进行重载和默认参数

语法:

~类名(){   }
//如果在类设计时,没有手动实现析构函数,然而编译器会提供一个默认的析构函数,
//该函数体为空,如果手动实现析构函数,编译器就不会再提供默认析构函数
class 类名
{
  public:
     //构造函数
     类名(参数列表)
     {
         
     }
     //析构函数
     ~类名()
     {
         
     }
  private:  
   //成员变量
};

以上是一个类设计时的基本模板

四、 构造函数初始化列表

类设计

????????类的成员变量

????????????????基本数据类型变量

????????????????cosnt 修饰的成员变量

????????????????static修饰的成员变量

????????????????类类型成员变量

????????类的成员函数

????????????????构造函数

????????????????析构函数

????????????????功能接口函数

????????????????运算符重载函数

如果类成员变量中有const来修饰的变量,要使用构造函数初始化列表来进行初始化
构造函数初始化列表语法:
构造函数(参数1,参数2,....,参数n):成员变量1(参数1),成员变量2(参数2),...,成员变量n(参数n)
{
    
}

class Test
{
public:
    Test(int t1=0,int t2=0):m_t2(t2)/*,m_t1(t1)*/
    {
       m_t1 = t1;
      // m_t2 = t2; //error
    }


    void printT()
    {
        cout << "m_t1 = " << m_t1 << "m_t2 = " << m_t2 <<endl;

    }
private:
    int m_t1;
    //由const修饰的成员变量,该变量是只读,不能通过接口来修改它的值
    const int m_t2 ; //如果类成员变量中有const来修饰的变量,要使用构造函数初始化列表来进行初始化,
                    //不能使用普通的构造函数的方式来初始化它
   // const int m_t2 = 100; //ok,但是不推荐它,原因在于,不是所有的C++版本支持此写法,C++11版本才支持

};

int main()
{

    Test t;
    t.printT();

    Test t2(10,20);
    t2.printT();

    return 0;
}

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-17 15:11:24  更:2021-08-17 15:13:12 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 7:33:35-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码