PoEdu培训 C++班 第八课 类和对象(6) const&static与类的化学反应
文章类别: 培训笔记 0 评论

PoEdu培训 C++班 第八课 类和对象(6) const&static与类的化学反应

文章类别: 培训笔记 0 评论

类和对象(6)

static与类

static成员变量结合

结合后的特性

// 举个例子
#include <iostream>

class Demo
{
public:
    Demo();
    ~Demo();

    static const int iNum = 0;    // 正确 可在类中直接赋值

    // static const double dNum = 0.0;    // 错误, 不能直接赋值
    static const double dNum;

    // static int iVal = 100;    // 错误, 不能直接赋值
    static int iVal;
    // static float fNum = 1.2f;    // 错误, 不能直接赋值
    static float fNum;
};


// 要在这里进行赋值
// 注意赋值的格式, 变量是什么样的  就需要写成什么样的

// static const double 类型的 dNum
const double Demo::dNum = 0.0;
// static float 类型的 fNum
float Demo::fNum = 1.2f;
// static int 类型的 iVal
int Demo::iVal = 100;

int main()
{
    using namespace std;

    cout << Demo::dNum << endl;
    cout << Demo::fNum << endl;
    cout << Demo::iNum << endl;
    cout << Demo::iVal << endl;

    return 0;
}

static成员函数结合

结合后的特性

总结

  1. static成员也是受访问权限控制符(private: public: protect:)控制的.
  2. 与成员变量结合后

    • 被所有对象共享的, 但是它不属于对象.
    • 通过类名直接访问. 类名::静态变量
    • 不占用我们类的大小(sizeof), 但是是占用内存空间的
  3. 与成员函数结合后

    • 没有this指针, 无法访问类中 非static 的成员(变量, 函数).

static应用 - 单例模式

// 举个例子说明一切

// 单例模式要求
//    1. 无法在外部进行构造新对象
//    2. 能够在外部来获取对象

// 这是非线程安全的单例
class Counter
{

private:
    // 无法在外部新建对象
    Counter(){};
    Counter(const Counter&){};
    Counter& operator=(const Counter& other){return *this;};
    ~Counter();

    static Counter* demoOther;

public:
    // 能够在外部来获取对象
    static Counter& GetInstance()
    {
        static Counter demo;
        return demo;
    }

    // 如下方式会导致内存泄露 
    // 因为只有new, 而没有delete 所以不会析构
    static Counter* getInstanceP()
    {
        if (!demoOther)
        {
            demoOther = new Counter;
        }
        return demoOther;
    }
    // 所以需要加上一个手动释放的方法来进行析构
    // 因为还没有学习到虚函数, 故此先不做考虑
    static void FreeP()
    {
        if (!demoOther)
            delete demoOther;
    }
};

Counter* Counter::demoOther;

int main()
{
    Counter& demo = Counter::GetInstance();

    Counter* demo1 = Counter::getInstanceP();
    // 如果不调用就会内存泄露
    Counter::Free();

    return 0;
}

const与类

// 举个例子
#ifndef _HADES_STRING_H_
#define _HADES_STRING_H_

#define _CRT_SECURE_NO_WARNINGS

#include <cstdio>
#include <cstring>
#include <string>

#define MAX_STR_LEN 255

namespace Hades
{
    class String
    {
    private:
        char* _szStr = nullptr;
        int _iLen = 0;

    public:
        // 构造函数
        String(const char* str = "");

        // 拷贝构造函数
        String(const String& other);

        // 析构函数
        ~String();

        //////////////////////////////////////////////////////////////////////////
        String& operator=(const String& other);

        //////////////////////////////////////////////////////////////////////////
        char& operator[](const size_t idx)
        {
            // const String& sz = static_cast<const String&>(*this);
            // char& cRet = const_cast<char&>(sz[idx]);
            // return cRet;
            // 来个经典的一句话
            return const_cast<char&>((static_cast<const String&>(*this))[idx]);
        }
        char& operator[](const size_t idx) const
        {
            return _szStr[idx];
        }

        //////////////////////////////////////////////////////////////////////////
        friend std::ostream& operator<<(std::ostream& os, const String& me);
        friend std::istream& operator>>(std::istream& is, String& me);
    };
}

#endif // _HADES_STRING_H_

int main()
{
    String demo("Hello Hades");
    const String demo1 = demo;
    cout << demo[3] << endl;    // 可以
    // 如果没有 const 版的operator[] 就不能调用
    cout << demo1[3] << endl;
}

我们的const对象只能访问const方法.

const与非const函数可以构成重载.

一般来说, operator[] 需要 const和非const两个版本.

重载const和非const 的默认约定:

小知识

如有错误,请提出指正!谢谢.

回复