一、类的功能阐述
今天我们将用目前学到的类的基础知识从头开始编写一个类。只编写一个基本的Log类,来演示到目前为止我们学过的一些基本特性。随着接下来的学习你会看到从一个类的基本版本到一个更高级版本的过程和区别。高级版本可以做同样的事情,但可以被认为是更好的代码。
我们来创建一个Log类,这个类是用来管理日志信息的一种方式,也就是把我们想要的信息打印到控制台上。这一般在调试程序时很有用。在我们程序中,如果你想知道发生了什么,只需要把事物的状态打印到控制台就行了。因为应用程序的控制台就像一个信息转储的地方,我们可以用它来显示发生了什么。
在游戏应用中如果我们要显示一个图形或者其他东西,这有时候会出问题,比如说图形渲染系统出问题了,或者其他的问题,我们就没法得到这些信息了。然而控制台是内置在操作系统的程序,所以我们几乎可以保证它总是能正常工作的。
我们来开始编写Log类,这里很简单,只是实现了向控制台发送文本的功能。而且可以控制我们发送给控制台日志信息的级别。最开始我们有三个级别。有error,warning和message(或者叫trace),简单来说,如果我们把日志级别设置为warning,那么只有warning和error级别的日志信息能打印出来,trace(或称为message)级别的不行。如果你只想看程序报了什么错或者有什么警告,这样设置是很有用的,不用看到一大堆无用的信息。通过过滤发送和打印的内容可以让控制台很清爽。
二、类的创建步骤
1、先创建一个Log类,
class Log
{
};
int main()
{
std::cin.get();
}
2、先写类的使用情况,就是我们打算用这个类干什么
现在先想一下Log类是如何工作的,创建一个类或者设计一个API很好的方式是研究它的使用情况。接下来进入main函数,开始编写我如何使用Log类。
class Log
{
};
int main()
{
Log log;//首先实例化一个Log类。
log.SetLevel(LogLevelWarning);//设置log级别,比如LogLevelWarning是指warning级别。这
//意味着只有警告(warning)或者错误(error)信息才会打印出来,trace信息不会。
log.warn(“”);//我要打印的警告信息是“”
std::cin.get();
}
3、完善类的成员函数及成员变量
通过上面log功能使用情况,我们就会知道我的Log类需要哪些功能了,让我们回过头去实现它们。
我们先实现外部能访问的方法,这个肯定是public的。
class Log
{
public:
void SetLevel(int level)
{
}
void warn( const char* message) //warn函数有一个字符串指针,是我们要打印的消息。
{
}
};
int main()
{
Log log;//首先实例化一个Log类。
log.SetLevel(LogLevelWarning);//设置log级别,比如LogLevelWarning是指warning级别。这
//意味着只有警告(warning)或者错误(error)信息才会打印出来,trace信息不会。
log.warn(“”);//我要打印的警告信息是“”
std::cin.get();
}
这里对于const char *message;
定义一个指向字符常量的指针,这里,message是一个指向 char* 类型的常量,所以不能用message来修改所指向的内容,换句话说,*message的值为const,不能修改。但是message的声明并不意味着它指向的值实际上就是一个常量,而只是意味着对message而言,这个值是常量。
程序运行查看结果:
这里的LogLevelWarning是不存在的,让我们声明log level变量,接下来我们将创建一些私有变量,代表我们的log级别。
#include<iostream>
#define log(x) std::cout<<x<<std::endl
class Log
{
private:
int m_loglevel;//声明日志级别这个成员变量
public:
void SetLevel(int level)//设置日志级别
{
m_loglevel = level;//把局部变量赋值给成员变量
}
void Warn(const char* message)//输出警告信息
{
}
};
int main()
{
Log log;
log.SetLevel(LogLevelWarning);
log.Warn("warningmessage");
std::cin.get();
}
为了让级别好记,比如LogLevelWarning,我们可以把它们设置成公有变量。
这里注意变量和方法分开,即使是相同的public,同样public static变量放在另一部分。
我们有三种日志级别,默认情况下为LogLevelInfo。
#include<iostream>
#define log(x) std::cout<<x<<std::endl
class Log
{
public:
const int LogLevelError = 0;
const int LogLevelWarning = 1;//定义LogLevelWarning为常量,数值为1.
const int LogLevelError = 0;
const int LogLevelInfo = 2;
private:
int m_loglevel=LogLevelInfo;//声明日志级别这个成员变量,并赋初值。
public:
void SetLevel(int level)//设置日志级别
{
m_loglevel = level;//把局部变量赋值给成员变量
}
void Warn(const char* message)//输出警告信息
{
}
};
int main()
{
Log log;
log.SetLevel(LogLevelWarning);
log.Warn("warningmessage");
std::cin.get();
}
最后我们来完善Warn函数,我们希望这个成员函数能打印信息到控制台,同时打印这条信息的级别。
#include<iostream>
#define log(x) std::cout<<x<<std::endl
class Log
{
public:
const int LogLevelError = 0;
const int LogLevelWarning = 1;//定义LogLevelWarning为常量,数值为1.
const int LogLevelInfo = 2;
private:
int m_loglevel=LogLevelInfo;//声明日志级别这个成员变量,并赋初值。
public:
void SetLevel(int level)//设置日志级别
{
m_loglevel = level;//把局部变量赋值给成员变量
}
void Warn(const char* message)//输出警告信息
{
if(m_loglevel>= LogLevelWarning)
std::cout<<"[warning]"<< message << std::endl;
}
void Info(const char* message)//输出警告信息
{
if (m_loglevel >= LogLevelInfo)
std:: cout<< "[Info]" << message << std::endl;
}
void Error(const char* message)//输出警告信息
{
if (m_loglevel >= LogLevelError)
std::cout << "[Error]" << message << std::endl;
}
};
int main()
{
Log log;
log.SetLevel(log.LogLevelWarning);
log.Warn("warningmessage");
log.Info("warningmessage");
log.Error("warningmessage");
std::cin.get();
}
测试没有问题。
4、要注意的问题
要注意的是LogLevelWarning是在类的内部定义的,我们使用的时候要加上log。