zoukankan      html  css  js  c++  java
  • C++ 第四天

    一、this指针
    1.1 什么是this 指针
    指向当前对象的指针
    构造函数中this指向正在被构建的对象首地址
    成员函数中 this代表调用这个函数的对象的首地址
    1.2 this指针的应用
    区分成员变量 和函数参数
    this 可以作为函数参数
    this 可以作为返回值(实现连续操作)
    二、const对象和const函数
    const对象就是加了const修饰对象
    const A a;
    const 函数就是加了const修饰的成员函数
    class A{
    public:
    void show()const{
    /*这就是const函数*/
    }
    void show(){
    /*这就是非const函数*/
    }
    };
    1.2 规则
    const 函数和非const函数可以构成重载关系
    const 对象只能调用const函数
    const 函数中只能读成员变量 不能修改成员变量的值 也不能调用非const的成员函数
    如果非要在const函数中去修改成员变量 只要在修饰的成员变量上 加一个mutable修饰
    非const对象优先调用非const函数,如果没有非const函数则调用const函数。
    #include <iostream>
    using namespcae std;
    class A{
    mutable int data;
    public:
    /*_ZK1A4showEv*/
    void show(){
    cout << "show()" << endl;
    }
    /*_ZNK1A4showEv*/
    void show()const{
    cout << "show()const" << endl;
    data=1101;
    cout << data << endl;
    }
    }
    int main(){
    A var_a;
    var_a.show();
    const A var_b=var_a;
    var_b.show();
    }

    三、析构函数
    3.1析构函数和构造函数同名 在函数名前加~,这个函数是无参的所以一个类型中
    只有一个析构函数
    3.2作用
    可以在一个对象销毁之前 自动调用一次。
    用来释放内存 释放资源
    3.3 内存相关的两个操作
    构造函数 分配内存
    析构函数 释放内存
    #include <iostream>
    using namespcae std;
    class A{
    int *data;
    public:
    /*构造函数中分配内存*/
    A():data(new int(10)){
    /*data= new int(10)*/
    cout << "A()" << endl;
    }
    /*析构函数 负责释放内存*/
    ~A(){
    cout << "~A()" << endl;
    delete data;
    }
    };
    int main(){
    A *pa = new A[5];//创建5个对象
    delete[] pa;
    }

    四.new delete 比malloc free
    new 比malloc多做了一些事
    1、如果类型中有类类型的成员 new会自动构建这个成员
    2、new 会自动处理类型转换
    3、new 会自动调用构造函数
    delete 比free多调用了一次析构函数
    #include <iostream>
    using namespcae std;
    struct Date{
    int year;
    int month;
    int day;
    Date(){
    cout << "Date()" << endl;
    }
    ~Date(){
    cout << "~Date()" << endl;
    }
    };
    class Person{
    int age;
    Date date;
    public:
    Person(){
    cout << "Person()" << endl;
    }
    ~Person(){
    cout << "~Person()" << endl;
    }
    };
    int main(){
    Person *p=static_cast<Person*>malloc(sizeof(Person));
    free(p);
    Person *p2 = new Person();
    delete p2;
    }

    五、拷贝构造函数
    5.1 概念
    本质上是一个构造函数 用拷贝数据的方式来构建对象
    5.2 语法
    Person(const Person&p){
    }
    如果不给一个类型提供拷贝构造函数 系统就默认提供一个拷贝构造函数
    #include <iostream>
    using namespace std;
    class Person{
    string name;
    int age;
    public:
    Person(string name,int age){

    }
    };

    int main(){
    Person p;

    }
    5.3 拷贝构造函数的调用时机
    1、使用一个已经存在的对象 去创建另外一个对象
    2、把对象传给一个函数的参数时
    3、把一个对象 作为函数返回值时
    4、为什么要有拷贝构造函数
    系统默认提供的拷贝构造函数 完成的是数据的逐字节拷贝。
    需要处理内存独立问题时 需要自定义拷贝构造函数。
    #include <iostream>
    using namespace std;
    class Person{
    string name;
    int age;
    public:
    Person(string name="",int age=0):name(name),age(age){

    }
    void show() const{
    cout << name << ":" << age <<endl;
    }
    /*写一个拷贝构造函数*/
    Person(const Person& p){//2、把对象传给一个函数的参数时,此处使用引用
    cout << "Person(Person)" << endl;
    name=p.name;
    age=p.age;
    }
    };

    void showPerson(const Person& p){
    p.show();
    }

    Person getPerson(const Person& p){//3、把一个对象 作为函数返回值时
    return p;
    }
    /*去掉拷贝
    const Person& getPerson(const Person& p){//3、把一个对象 作为函数返回值时
    return p;
    }
    */
    Person getP(){
    /*Person p;
    return p;*/
    /*匿名对象简化 编译器优化只有一次构造*/
    return Person("qwer",123);
    }

    int main(){
    Person pa("xiaoming",12);
    Person pb=pa;//1、使用一个已经存在的对象 去创建另外一个对象
    pb.show();
    showPerson(pb);//2、把对象传给一个函数的参数时
    Person p=getPerson(pa);
    }
    深拷贝和浅拷贝
    #include <iostream>
    using namespace std;
    class Array{
    /*最大容量*/
    int cap;
    /*多少个元素*/
    int size;
    /*真正存储数据的区域*/
    int *data;
    public:
    Array(int cap=5):cap(cap),size(0){
    date=new int[cap];
    }
    ~Array(){
    delete[] data;
    }
    Array(const Array& a){//深拷贝
    cap=a.cap;
    size=a.size;
    /*重新申请内存空间*/
    data=new int[cap];
    /*复制数据*/
    for(int i=0;i<size;i+){
    data[i]=a.data[i];
    }
    }

    };
    int main(){
    Array arra;
    Array arrb=arra;
    }
    六、静态成员
    6.1不需要对象 就可以调用函数,通过类型就可以完成这种函数的调用。
    #include <iostream>
    using namespace std;
    class A{
    public:
    void fooa(/*A *this*/){//普通成员函数
    cout << "fooa()" << endl;
    cout << this->x << endl;
    cout << thsi->y << endl;
    }
    static void foob(){
    cout << "foob()" << endl;
    //cout << x << endl;
    cout << y << endl;
    }

    static void fooc(A *mythis){
    cout << mythis->x << endl;
    }

    };
    int A::y=1;
    int main(){
    A a;
    a.fooa();
    A::foob();
    }
    6.2静态成员变量
    静态成员变量 是整个类型共用的变量。
    普通成员变量 是对象独有的。
    静态成员变量 必须在类外进行初始化。
    class A{
    int x;
    /*静态成员变量*/
    static int y;
    };
    /*基本类型赋值成零,类类型默认调用无参构造*/
    静态成员变量类型 类名::变量名;
    6.3静态成员函数 和 静态成员变量
    静态成员函数中只能(直接)访问静态成员。
    /*静态函数中没有this指针*/
    不能直接访问非静态成员。

    静态成员 就是受类名作用域和权限限制的全局数据。
    6.4 单例模式的实现
    一个进程中 这种类型的对象只有一个
    #include <iostream>
    using namespace std;
    class Singleton{
    private:
    Singleton(){}
    Singleton(const Singleton& s){}
    static Singleton sig;
    public:
    static Singleton& getInstance(){
    return sig;
    }
    };

    Singleton Singleton::sig;//静态成员变量 必须在类外进行初始化

    int main(){
    Singleton& sig=Singleton::getInstance();
    }

  • 相关阅读:
    lsb_release -a 查询Linux系统版本
    html常用标签
    js判断对象是否为空
    springBoot2.x 支持跨域请求配置
    httpclient 上传附件实例
    js 使用sessionStorage总结与实例
    性能测试需求调研分析方法
    jmeter压测实践
    页面加载时调用js函数方法
    IntelliJ IDEA 界面介绍及常用配置
  • 原文地址:https://www.cnblogs.com/Malphite/p/9904077.html
Copyright © 2011-2022 走看看