首页 > 编程语言 > 详细

标准C++03

时间:2020-09-19 13:15:51      阅读:59      评论:0      收藏:0      [点我收藏+]
类的成员变量存储在每个类对象中(每个对象一份),成员函数存储在代码段中(所有的对象共享一份),那么成员函数是如何区分调用它的是哪个对象?
    答:与C语言的解决方案一样,把对象的地址传递给成员函数,这样成员函数就知道是哪个对象在调用它,与C语言不同的是该操作是隐藏,编译器帮我们自动完成的,也就是类的成员函数都隐藏着一个参数,这个参数就是this指针。

this指针:
    指向访问成员函数对象的指针,默认是隐藏的,但也可以显示使用。
     
    对象调用成员函数时会自动计算它的内存地址传递给成员函数中的this,而在成员函数调用其它成员函数,会把对象的地址接力传递下去。
        
    构造函数中也有this指针,指向这个正在构造的对象,原因是构造函数执行前对象所需的内存就已经分配完毕,执行构造函数的目的是为了申请其它资源、做一些准备工作,对指针成员分配内存。

    this指针的用法:
        1、函数参数与成员变量重名,参数会屏蔽成员变量,可以通过this指针访问成员变量。
        2、如果成员函数需要返回当前对象的地址或引用,可以使用this指针完成。
        3、可以把this指针传递其它类对象,这样可以实现对象间的交互。
二、常函数
    如果对象被const修饰,那么它就不能调用普通的成员函数,因此普通成员函数的this指针没有被const修饰,而const对象在调用成员函数传递的对象指针带const属性,因此不兼容。

    在类的成员函数末尾用const修饰一下,就表示用const修饰该成员函数的this指针,这种函数叫常函数,cosnt对象只能调用常函数,常函数也只能调用函数。

    如果一个成员函数可能const对象和非常对象调用,则可以重载,实现两个版本,const指针和非const指针可以影响函数的重载。

    如果在常函数中要修改成员变量值,可以使用mutable修饰成员变量即可。

三、拷贝构造
    拷贝构造也是一种构造函数,只是参数一个旧的对象,当使用旧对象给新创建的对象初始化时将调用拷贝构造。
        类名(const 类& that)
        {

        }
    默认情况下编译器会自动生成一个拷贝构造函数,该函数负责把旧对象中的数据拷贝给新的对象。

    深拷贝与浅拷贝:
        如果类的成员中有指针,在拷贝时只拷贝指针变量的值,这种叫浅拷贝,深拷贝是拷贝指所指向的数据。
        注意:默认的拷贝构造只能完成浅拷贝。

    什么情况要重写拷贝构造:
        当类中的成员有指针时,想完成深拷贝的效果,就需要重写拷贝构造。
        
    什么情况下会调用拷贝构造:
        1、使用旧对象给新对象初始化时
            Test t1 = t;
        2、使用对象作为函数的参数或返回值时。

四、赋值运行符
    使用旧对象给其它对象赋值时,调用赋值运行符,它的任务就是把对象a中的数据拷贝给对象b,默认情况下也是浅拷贝。
    void operator=(const 类& that)
    {

    }
    当你需要重写拷贝构造时,也就需要重写赋值运算符。
    常用考笔试题:实现string类的构造、拷贝构造、赋值运算符、析构函数。
        class String
        {
            char* str;
        public:
            String(const char* str="");
            ~String(void);
            String(const String& that);
            void operator=(const String& that);
        };
        
五、关于拷贝构造和赋值函数的建议
    1、拷贝构造和赋值函数不光会赋值本类的数据,也会调用父类和成员类的拷贝构造和赋值函数,而不是单纯的内存拷贝,因此尽量少使用指针成员。

    2、函数的参数中尽量指针和引用,减少调用拷贝构造的次数,这样也可以提高传递的效率。

    3、如果由于特殊原因无法实现拷贝构造和赋值函数,可以把实现个空的然后私有化,防止误用。

    4、一旦实现了拷贝构造也要实现赋值函数,反之亦然。

六、静态成员
    类的成员变量可以被static修饰,存储位置由原来的栈或堆变成data或bss,整个程序中只存在一份,被所有的对象共享(静态成员属于类,而不是某个对象)。

    静态成员变量在类中声明,但必须在类外定义、初始化,与其它在类外的成员函数一样,需要加 类名:: 表示它属于哪个类,但不需要再加static。

    静态成员变量虽然在类定义,但它依然受访问控制符的限制,私有成员和保护成员只能在类内访问。

    静态成员变量不需要对象就可以访问,类名::静态成员变量名,public静态成员变量可以当全局变量使用。

    静态成员函数也可以被static修饰,这种成员参数中就没有隐藏this指针,因此静态成员函数不需要对象就可以访问,类名::静态成员函数名,也就导致静态成员函数中不访问成员变量,也不能调用其它成员函数。

    普通成员函数中可以直接访问类的静态成员变量和静态成员函数。

    静态成员的作用:
        静态成员变量可以当作类范围内的"全局变量使用"。
        而静态成员函数可以作为其它函数的回调函数,或者当作类的接口,实现对类的管理。
    常见的面试:C语言中的static与C++的static有什么区别?
        在C语言static具有限制作用域、改变存储位置、延长生命周期的功能。
        在C++中static又增加了新功能,可以修饰类的成员变量和成员函数。
        静态成员变量:
            存储位置由原来的栈或堆变成data或bss,整个程序中只存在一份,被所有的对象共享。
            在类里面声明,在类外定义,访问时不需要对象,依然受访问控制限定符控制,只有public可以在类外访问被当作全局变量使用。
        静态成员函数:
            没有隐藏的this指针,不需要对象就可以调用,不能在函数访问成员变量和成员函数,但可以被其它成员函数调用。
            可以让类的成员函数当作回调函数,可以当作类的管理接口。

七、单例模式
    只能创建出一个对象的类叫单例模式。
    单例模式的应用场景:
        1、Windows系统的任务管理器。
        2、Linux\UNIX系统的日志管理系统。
        3、网站的访问计数器。
        4、服务器的连接池、线程池、数据池等。
    创建单一对象的方法:
        1、定义全局的,但不受控制,且有再次创建的风险。
        2、专门实现一个类,把类的构造函数调用为私有,然后借助静态成员函数提供一个获取唯一对象的接口。
    C++实现单例的思路:
        1、禁止类外创建类对象:把构造和拷贝构造设置为私有的。
        2、类自己维护一个对象:使用静态指针或静态对象。
        3、提供一个获取实例的方法:使用静态成员函数获取静态对象。
    懒汉模式:
        用静态成员指针来指向唯一的单例对象,只有真正调用单例接口时才创建对象。
        优点:什么时候用什么时候创建,节约内存、资源。
        缺点:只有在调用获取接口时才创建对象,当多个线程同时调用该接口时,可能会创建出多个对象,存在线程不安全问题。

    饿汉模式:
        将单例对象设置为类的静态成员变量,在main函数开始运行前,实例对象就已经创建完成。
        优点:获取单例对象时,线程安全。
        缺点:无论是否使用,单例对象都已经创建完成,浪费内存、资源。

标准C++03

原文:https://www.cnblogs.com/Nxet/p/13695259.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!