C++ 语言学习 day02 (linux ) delete 函数 面对对象的类,构造函数,析构函数

一、new的使用
    格式1: 指针名 = new 类型;
    格式1: 指针名 = new 类型(初始化值 );
    格式1: 指针名 = new 类型[元素个数];


   2.释放内存
      格式1:delete 指针名
      格式2: delete[] 指针名    只正对于new数组的情况 



  
  3.new malloc的区别(面试题)
    第一点:new是c++的,malloc是c的。
    第二点:new是运算符  ,malloc是函数,new要快于malloc
    第三点:malloc申请失败返回NULL,new申请失败返回异常;
    第四点: new和malloc都是在堆区申请的内存
    第五点:new是创建对象,创建的对象不需要强转,malloc需要 
    第六点: new的申请需要delete释放,malloc的申请需要free


   4. 注意: new 和delete是运算符  不是函数。


代码:

#include <iostream>


using namespace std;
struct student
{
    int age;
};
int main()
{
    char* pc = new char(0);
    int * pi = new int;
    double * pd = new double[10];
    struct student* ps = new struct student;


    delete pc;
    delete pi;
    delete[] pd;
    delete ps;
}

二、类型转换
     c语言类型转换  (类型)变量名
     c++四种
           第一种: const_cast     把const类型变量转换成非const类型变量
           格   式:const_cast<类型> (变量名)
           练   习: 定义const指针变量,转换成非const,然后修改值后打印出来
            注意: 尖括号不可以省略 小括号不要省略
                       const_case 的尖括号中必须是指针或者引用类型



         第二种:dynamic_cast  
             作用: 用于多态中类型的转换。(暂时不讲)



         第三种:static_cast
         作用:用于基本数据类型转换,也可以用于不同类对象的转换(父子类)
         格式: static_cast<类型>(变量)
                 double 转换成int
         特点:不会进行安全检查。



       第四种:reinterpret_cast 
         作用: 属于底层的强制类型转换,进行二进制的数据拷贝。
         使用: reinterpret_cast <类型>(变量名)


代码:

#include <iostream>

int main()
{
 
    //第一种数据类型转化
    int z = 10;
    const int* y =  &z ;
    int* x = const_cast<int*> (y);
       cout << (*x) <<endl;
    //第二种数据类型转化
    double db = 123.8456;
    int idb = static_cast<int>(db);
    idb++;
    cout << idb <<endl;


    
}


三、面向对象
      1.面向对象编程(oop)
      主要是为了隔离数据,保护内部数据不被随意修改,同时限定变量的使用区域



      
      2.类定义
         定义一个类,有属性(成员变量),有行为(成员函数)。
        格式: class  类名
                   {
         修饰符:
                         定义变量;
                         定义函数;
                   };



      3.c++中结构体和类的区别
        第一个:在结构体中,默认为共有属性,而在类中是私有属性。



      4.成员修饰符
        共有属性: public:   可以在类内使用(类内函数中),可以在类外使用,可以在子类中使用。
        私有属性: private      只可以用于当前类内使用,类外和子类没法使用
        保护属性: protected:当前类内使用,子类使用。



     5.定义对象:类名 对象名;
                        对象名.成员变量;
                        对象名.成员函数();
                        对象指针 = new 类名称;  使用成员变量是需要用->  
                        对象指针->成员变量
                        对象指针->成员函数();  



     6.声明和实现分离
       原因:类什么和实现分离时为了隐藏实现部分。
                 实现接口化编程;
       格式:
                 定义类: class student {public: void show(); };
                 类外实现: void student::show(){cout <<age <<endl;}



   
      7.成员变量的set和get方法(私有)
         get是获取成员变量的值
         set是设置成员变量的值。


代码:

#include <iostream>
using namespace std;

class person
{
public:
    int age ;

    char* name;
    void show()//类内定义
    {
        cout << age <<endl;
    }
    void display(); //类内声明
    int getMoney()
    {
        return money;
    }
    void setMoney(int a)
    {
        age = a;
    }
private:
    int money;
   
};
//类外实现。
void person::display()
{
    cout << money<<endl;
}

class student
{
private:
    int age = 10;
public:
    char* name= "abc";
    void show();
};

class mynull{};//大小是1

void student::show()
{
    cout << age <<endl;
}

int main()
{
    person danny;
    danny.age = 12;

    student huaqing;
   // cout << huaqing.name <<huaqing.age << endl;
    huaqing.show();
    cout << sizeof(mynull)<<endl;
    //new的方式创建对象
    student * pstu = new student;
    pstu->name;
    danny.setMoney(100000000);
    cout << danny.getMoney()<<endl;

    return 0;
}


四、构造和析构
       1构造函数:用来构造对象,每个对象创建时都会调用构造函数。
                       如果没有手动写构造,编译器会自动添加一个。
                       构造用来做初始化处理,变量的赋值,申请内存。



       2格      式: 类名(参数){ 内容}
       3注      意:构造函数的函数名是类名相同
                       构造函数没有返回值
                       构造函数有参合无参构成了重载
                       默认的构造函数,没有参数的函数版本 student(){ }
                       只要手动添加了构造,默认的构造就会消失。
                       只要手动添加的构造,都必须要有无参构造。(养成好习惯)



  
       4构造调用:构造函数不需要主动调用,当定义对象时会自动调用
                      对于有参构造,在定义对象时需要加小括号和参数,例如 stduent danny(10);
                     对于无参构造,直接类名+对象名构建对象,不需要加括号 例如 student danny;
                      如果某一个对象当做函数的参数,为了防止内存拷贝,需要使用引用。



        
      5.析构函数
         作用:在对象释放时内核自动调用析构函数
                   用来释放内存空间,用来关闭句柄等善后操作
         格式:~类名(){}
         注意:析构函数的名称是在类名前加~
                   析构函数不可以主动调用
                   析构函数没有参数,不可以有参数。
                   如果没有手动添加析构,编译器会自动添加析构函数。
         案例:
            class student    {
                private:      int age;
                public:    student(int a);
                                student();
                               ~student(){};
             void setAge(int a)    {       age = a;    }
             int getAge()    {        return age;    }
         };



   6. 拷贝构造
         拷贝构造:他是一种特殊的构造 (没有返回值,函数名是类名),特殊在参数是另外一个对象。
        格式: 类名(类名& 对象名){xxxx}
        调用: student dannyzai(danny);
                   student dannyzai = danny;  拷贝构造
                   fun(student abc){}  //避免拷贝构造 加引用


代码:

//  写一个代码:定义一个point类,
//  有x和y坐标(int*),定义构造和拷贝构造,
//  定义析构,在main函数中定义对象。(出现什么错误)

#include <iostream>
#include <cstring>
using namespace std;

class point{
private:
    int* x;
    int* y;
public:
    void setX(int a)
    {
        *x = a;
    }

    point(){  //无参构造
        x = new int(0);
        y = new int(0);
    }
    point(int a,int b){//有参构造
        //x = a;
        x = new int(a);
        y = new int(b);
    }
    point(int* a,int* b)//有参构造
    {
        //错误 x= a;y= b
        x = new int (*a);
        y = new int(*b);
    }
   point(point  &a);//拷贝构造
}

point::point(point& a){
       /* x = a.x;
        y = a.y;*/
    if(x != NULL)
    {
        delete x;
    }
    if(y!= NULL)
    {
        delete y;
    }
    // 
    if(this !=  &a)//防止引用自己  
    {
        x = new int(*a.x);
        y = new int(*a.y);
    }
    cout << "abc"<<endl;
}

int main(int argc ,char* argv[])
{
    point p1;  //p1.x  p1.y
    point p2 = p2;  //p2.x = p1.x  p2.y = p1.y    错误 doulbe free 两次释放
    point p3(10,20);
    int * pa = new int(10);
    point p4(pa,pa);
    delete pa;
    p4.setX(10);
    return 0;
}



   7.拷贝方式:
     浅拷贝:浅拷贝只是拷贝了指针指向,不申请内存空间,存在多次释放相同内存的危险,需要避免使用。
     注意:如果没有手动写拷贝构造,编译器会自动添加默认的浅拷贝构造函数。
              在拷贝构造函数中 要防止自拷贝 if(this != &other)
              在拷贝构造中,如果指针不为空,需要先释放内存再进行申请
      深拷贝:深拷贝拷贝的是另一个对象的内容,不拷贝地址,新的对象有自己单独的内存空间,不会进行double free的情况。
 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习编程?其实不难,不过在学习编程之前你得先了解你的目的是什么?这个很重要,因为目的决定你的发展方向、决定你的发展速度。
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面设计类、前端与移动、开发与测试、营销推广类、数据运营类、运营维护类、游戏相关类等,根据不同的分类下面有细分了不同的岗位。
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生学习Java开发,但要结合自身的情况,先了解自己适不适合去学习Java,不要盲目的选择不适合自己的Java培训班进行学习。只要肯下功夫钻研,多看、多想、多练
Can’t connect to local MySQL server through socket \'/var/lib/mysql/mysql.sock问题 1.进入mysql路径
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 sqlplus / as sysdba 2.普通用户登录
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服务器有时候会断掉,所以写个shell脚本每五分钟去判断是否连接,于是就有下面的shell脚本。
BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
假如你已经使用过苹果开发者中心上架app,你肯定知道在苹果开发者中心的web界面,无法直接提交ipa文件,而是需要使用第三方工具,将ipa文件上传到构建版本,开...
下面的 SQL 语句指定了两个别名,一个是 name 列的别名,一个是 country 列的别名。**提示:**如果列名称包含空格,要求使用双引号或方括号:
在使用H5混合开发的app打包后,需要将ipa文件上传到appstore进行发布,就需要去苹果开发者中心进行发布。​
+----+--------------+---------------------------+-------+---------+
数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,比如 numbers,然后使用 nu...
第一步:到appuploader官网下载辅助工具和iCloud驱动,使用前面创建的AppID登录。
如需删除表中的列,请使用下面的语法(请注意,某些数据库系统不允许这种在数据库表中删除列的方式):
前不久在制作win11pe,制作了一版,1.26GB,太大了,不满意,想再裁剪下,发现这次dism mount正常,commit或discard巨慢,以前都很快...
赛门铁克各个版本概览:https://knowledge.broadcom.com/external/article?legacyId=tech163829
实测Python 3.6.6用pip 21.3.1,再高就报错了,Python 3.10.7用pip 22.3.1是可以的
Broadcom Corporation (博通公司,股票代号AVGO)是全球领先的有线和无线通信半导体公司。其产品实现向家庭、 办公室和移动环境以及在这些环境...
发现个问题,server2016上安装了c4d这些版本,低版本的正常显示窗格,但红色圈出的高版本c4d打开后不显示窗格,
TAT:https://cloud.tencent.com/document/product/1340