类和对象(6)
static与类
static与成员变量结合
结合后的特性
- 表示它
不属于对象, 而是属于类的_ - 所有对象中都会共有
需要在外部单独赋值
- 冷知识:
- 除非它是一个
static const int 类型可以在类中直接初始化
// 举个例子
#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与成员函数结合
结合后的特性
- 成员函数
不再属于对象, 而是属于类 - 使用
类名::函数名方式进行调用 结合后, 函数内
没有this指针, 这就意味着函数内不能访问对象属性- 所以, static的函数
不能访问非static的成员 - 冷知识:
- 非静态成员可以访问静态成员.
- 但是, 它虽然在
语法层面上没错, 但是这种做法是有问题的.
- 所以, static的函数
总结
- static成员也是受
访问权限控制符(private: public: protect:)控制的. 与成员变量结合后
- 被所有对象共享的, 但是它不属于对象.
- 通过类名直接访问.
类名::静态变量 - 不占用我们类的大小(sizeof), 但是是占用内存空间的
与成员函数结合后
- 没有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 的默认约定:
- 非 const函数 会去调用 const函数
小知识
- 全局变量不要放到 .h 中
如有错误,请提出指正!谢谢.
本文由 花心胡萝卜 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: 2017-02-08 at 10:13 am