可见性对性能没有任何影响,也不会产生不同的代码。只是人为规定,用于提示,可以类比类型的定义。
基类 | 友元 | 子类 | 外部 | |
---|---|---|---|---|
public | ✅ | ✅ | ✅ | ✅ |
protected | ✅ | ✅ | ✅ | ❌ |
private | ✅ | ✅ | ❌ | ❌ |
可见性的意义:
允许或不允许自己或其他人访问类中的特定成员。将不想被直接访问的成员定义为private,保证代码的正常运行。
小例子:
一个摇杆控制方向的UI界面。该类定义如下:
class UI
{
private:int x;int y;
public:void refresh(int direction){// 用于刷新显示界面,控制摇杆移动方向}void move(int direction){// 判断哪个方向移动多少,改变xy坐标值// 并刷新显示,产生摇杆往对应方向移动的显示refresh(direction);}
};
如果直接修改xy的值,摇杆移动的画面时无法显示的。
本质区别:在不声明是public还是private的情况下,class默认是private,而struct默认是public。除此以外,本质上🈚️区别了。
一般情况下,struct用来维护数据,class用于更复杂的功能,如继承等。另外一个角度来看,用class来实例对象(产生个体)。
不同的成员可以分开写,即使他们的可见性是相同的
例如将公共的数据和函数分别写在两个public中,这样比较好维护
这个小例子是一个关于日志输出的类:
class Log
{
public:const int LogLevelError = 0;const int LogLevelWarning = 1;const int LogLevelInfo = 2;
private:int m_LogLevel = LogLevelInfo;
public:void SetLevel(int level){m_LogLevel = level;}void Error(const char* message){if (m_LogLevel>=LogLevelError)cout << "[ERROR]:" << message << endl;}void Warn(const char* message){if (m_LogLevel>=LogLevelWarning)cout << "[WARNING]:" << message << endl;}void Info(const char* message){if (m_LogLevel>=LogLevelInfo)cout << "[INFO]:" << message << endl;}
};int main(){Log log;log.SetLevel(log.LogLevelWarning);log.Warn("Hello");log.Error("Hello");log.Info("Hello");// 输出有WARNING和ERROR
}
枚举其实是一个人为添加的限制,尤其适用于不同状态要有对应操作的情况下,比如上述的Log。
要定义所有代表状态的变量并完成赋值,使用枚举可以将这些状态变量集中在一起定义,并且自动赋值(可以自己给任意变量赋值,如果不赋值,则默认第一个变量为0,其他变量值为前一个变量值+1),增加代码可读性。另外,也可以防止其他部分代码修改表示状态的变量值。
这里需要强调:
所有枚举变量值都是整数,但这不代表变量一定是int类型,这里回忆之前类型章节所述。由于枚举变量都是整数,因此可以将枚举变量定义成可以接受整数的类型,如char等,这意味着float、double是不行的。由于不同类型变量占用的空间不同,根据状态个数选择合适类型可以节省空间。
将上述Log用枚举实现:
class Log
{
public:enum Level : char{// 命名需要注意,变量不要和函数重名,// 所以这里都加上了Level作为前缀来区分变量LevelError = 0, LevelWarning, LevelInfo};
private:int m_LogLevel = LevelInfo;
public:void SetLevel(int level){m_LogLevel = level;}void Error(const char* message){if (m_LogLevel>=LevelError)cout << "[ERROR]:" << message << endl;}void Warn(const char* message){if (m_LogLevel>=LevelWarning)cout << "[WARNING]:" << message << endl;}void Info(const char* message){if (m_LogLevel>=LevelInfo)cout << "[INFO]:" << message << endl;}
};int main(){Log log;log.SetLevel(Log::LevelWarning);log.Warn("Hello");log.Error("Hello");log.Info("Hello");// 输出有WARNING和ERROR
}
负责类的初始化,与类同名,可重载
class Entity
{
public:float X,Y;// 构造1Entity(){X = 0;Y = 0;}// 构造2Entity(float x, float y){X = x;Y = y;}void Print(){cout << X << ',' << Y << endl;}
};int main(){// 不同构造方式Entity a;Entity b(1,1);a.Print();b.Print();// 输出0,0和1,1
}
工具类:如果一个类只有一些静态函数,我们不希望使用者实例化这个类的对象,而是直接使用这个类中的方法,这就需要对构造函数进行操作:
方式1:构造函数私有化
方式2:删除构造函数(推荐)
// 方式1
class Log
{
private:Log(){}
public:static void Write(){// 巴拉巴拉}
};// 方式2
class Log
{
public:Log() = delete;static void Write(){// 巴拉巴拉}
};
在使用构造函数初始化类成员变量时,成员初始化列表是更好的方式。需要注意的是列表顺序必须和类成员变量声明顺序一致。
class Entity
{
public:string m_Name;int m_Score;
public:// 使用成员初始化列表Entity(): m_Name("Unknow"), m_Score(0) // 冒号后面接列表{// balabalacout<< m_Name << endl;cout<< m_Score << endl;}// 优于不使用成员初始化列表
// Entity()
// {
// m_Name = "Unknow";
// m_Score = 0;
// cout<< m_Name << endl;
// cout<< m_Score << endl;
// }
};
这样代码很简洁,可以把变量赋值和其他功能分开。而且有利于提升性能:
class Example
{
public:Example(){cout<< "Created Entity" << endl;}Example(int x){cout<< "Created Entity with "<< x<< "!"<< endl;}
};class Entity
{
public:Example m_Example;
public:// 成员初始化列表的方法// 输出只有Created Entity with 8!Entity(): m_Example(Example(8)) //写成m_Example(8)也可以{}// 不使用的话,输出为Created Entity和Created Entity with 8!
// Entity()
// {
// m_Example = Example(8);
// }
};
这里可以看到,不使用成员初始化列表的话,Example会被创建两次,相当于先用无参数构造对象,然后又用有参数构造对象并替换了之前无参数的对象,影响性能。不使用的代码等价于如下:
class Entity
{
public:Entity(){// 构造两次Example m_Example;m_Example = Example(8);}
};
清理使用的内存,销毁(delete)或作用域结束(如函数中创建对象)时使用。比如动态申请空间后(new),需要在析构函数中释放该空间,否则这些内存空间将被一直占用,直到程序结束。动态申请的这些空间都在堆中,需要开发者自行释放。
class Entity
{
public:Entity(){cout<<"Create Entity"<< endl;}// ↓就是这玩意~Entity(){cout<<"Destory Entity"<< endl;}
};int main(){Entity e;
}
本文发布于:2024-01-29 10:20:42,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170649484514601.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |