[C++学习笔记05]对象的使用

  1. static成员
      普通static成员
        必须在类体外定义。
      特殊static const成员
        整型(int,char,short,long等)static const成员
          可以不需要在类体外定义,如果没有在类外部初始化,必须在类体内初始化(常量)。
        非整型static const成员
          非整型不能像整型那样,不允许在类体初始化,只能在类外定义初始化。
    #include <iostream>
    using namespace std;
    class Test {
    public:
        static int a; // 1普通的static成员变量,不能在类体内初始化
        static const int b=10; // 2static const int(整型), 可以不需要在类体外定义,如果没有在类外部初始化,必须在类体内初始化(常量)
        static const double c; // 3static const double 非整型不能像整型那样,不允许在类体初始化
        static const char d=11; // 2char和int都是整型 一样的,可以不需要在类体外定义,如果没有在类外部初始化,必须在类体内初始化(常量)
    };
    
    int Test::a; // 1普通的static成员必须在类体外定义,可以不需要初始化,默认值0
    const double Test::c=10; // 3static const double 非整型必须在类体外定义(并必须初始化)
    int main(void)
    {
        Test a;
        cout << a.a << endl;
        cout << a.b << endl;
        cout << a.c << endl;
        cout << Test::d << endl;return 0;
    }
  2. static成员函数
       static成员函数没有this指针
      非静态成员函数可以访问静态成员
      静态成员函数不可以访问非静态成员
  3. 类/对象大小计算
      
    类大小计算遵循前面学过的结构体对齐原则
      类的大小与数据成员有关成员函数无关
      类的大小与静态数据成员无关
      虚函数对类的大小有影响(虚表指针)
      虚继承对类的大小有影响

  4. 四种对象作用域与生存期
      
    说明:作用域和生存期不总是等同的。
      栈对象
         隐含调用构造函数(程序中没有显示调用)
      堆对象
         隐含调用构造函数(程序中没有显示调用)
      全局对象、静态全局对象
         全局对象的构造先于main函数
        已初始化的全局变量或静态全局对象存储于.data段中
        未初始化的全局变量或静态全局对象存储于.bss(block started by symbol)段中
      静态局部对象
         已初始化的静态局部变量存储于.data段中
        未初始化的静态局部变量存储于.bss段中

    关于.bss,.data段的区别
      .bss可执行文件中不占用空间,因为初始值为0,只需要一个符号。block started by symbol,程序加载才分配.bss段。
      .data可执行文件中占用空间
    关于静态普通对象与静态类对象初始化的区别
      

  5. static用法总结
    C语言中
      1.用于修饰函数内部的变量,延长变量的生存期,使得函数有一定的“状态”。属于不可重入函数(线程不安全函数)
      2.在文件中修饰变量或者函数,使之只在本文件中可见,具有internal linkage,别的文件extern是不行的。
    C++语言中
      除了C语言中的两种用法在加上类中的成员变量成员函数的修饰。
    注:如果在.h文件中定义全局变量会导致多个源文件包含时重定义,最好的做法是在一个源文件中定义全局变量,另一个源文件中使用extern(称为external linkage),也可以在.h中使用extern语句,当然在.h中定义全局静态变量是不会出现重定义的

  6. static与单例模式
      实现单例模式的几点注意:
        1.保证一个类只有一个实例,并提供一个全局访问点;
        2.禁止拷贝(将拷贝构造函数与=数声明为private,并且不需要提供实现)。
      实现单例模式的方式:
        1.通过像定义getInstance一样的静态函数实现手动的Free静态函数即可,当你要析构对象,直接调用Free函数即可。
        2.通过嵌套类,外围类中定义一个嵌套类的静态成员,在嵌套类中的析构函数中delete instance即可。
    class Singleton {
    public:
        Singleton()
        {
            cout << "Singleton ... " << endl;
        }
        static Singleton *getInstance()
        {
            if (instance_ == NULL)
            {
                instance_ = new Singleton;
            }
            return instance_;
        }
        ~Singleton()
        {
            cout << "~Singleton ... " << endl;
        }
    
        // 嵌套类实现析构
        class Garbo {
        public:
            ~Garbo()
            {
                if (instance_ != NULL) {
                    delete instance_;
                }
            }
        };
    private:
        static Singleton *instance_; // 1不能析构
        static Garbo gb_;
        Singleton(const Singleton &s);
        Singleton &operator=(const Singleton &s);
    };
    
    Singleton *Singleton::instance_; // 1不能析构
    Singleton::Garbo gb_; // 通过使用嵌套类来实现程序结束,自动析构单例对象
    
    int main(void)
    {
        Singleton *s1 = Singleton::getInstance();
        Singleton *s2 = Singleton::getInstance();
    
        //Singleton s3(*s1); // 防止拷贝
        
        //Singleton s3;
        //s3 = *s1; // 防止拷贝
    
        return 0;
    }

        3. 直接通过在函数中定义一个static的对象,然后返回引用或者指针(较为简单的方式)

    class Singleton {
    public:
        Singleton()
        {
            cout << "Singleton ... " << endl;
        }
        static Singleton &getInstance()
        {
            // 直接通过在函数中定义一个static的对象,然后返回引用或者指针都行,比较简单的方式
            // 当程序结束时,instance自动析构
            static Singleton instance;
            return instance;
        }
        ~Singleton()
        {
            cout << "~Singleton ... " << endl;
        }
    private:
        Singleton(const Singleton &s);
        Singleton &operator=(const Singleton &s);
    };
    
    int main(void)
    {
        Singleton &s1 = Singleton::getInstance();
        Singleton &s2 = Singleton::getInstance();
    
        return 0;
    }
  7. const成员函数
      const成员函数与非const成员函数构成函数重载
      const成员函数只能访问数据成员的值,而不能修改它;
      const成员数可以修改使用mutable关键字修饰的成员变量
      const对象只能调用const成员函数,非const对象既能调用const成员函数,也能调用非const成员函数。
    class Test {
    public:
        Test(int num = 0) : num_(num)
        {
            count_ = 0;
        }
    
        // const 成员函数与非const成员函数构造函数重载
        // 非const对象调用非const成员函数,也可以调用const成员函数,const对象只能调用const成员函数
        int getNum()
        {
            cout << "getNum()" << endl;
            count_++;
            return num_;
        }
    
        int getNum() const
        {
            cout << "getNum() const" << endl;
            count_++;
            return num_;
        }
    
        void showCount() const
        {
            cout << count_ << endl;
        }
    
    private:
        int num_;
        mutable int count_; // count只是用来统计获取的次数,希望在const成员函数中修改。
    };
    
    int main(void)
    {
        Test t;
        t.getNum();
    
        // const 对象
        const Test t2;
        t2.getNum();
        t2.getNum();
        t2.getNum();
    
        t2.showCount();
        return 0;
    }

转载于:https://www.cnblogs.com/ifpelset/articles/4509595.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值