nocopyable
//以前的那种是语言级别的,这个是编译器级别的
#pragma once
/*
原理:
派生类的拷贝构造和赋值,肯定要先调用基类的拷贝构造跟赋值
采用这种方式,可以让派生类直接无法拷贝构造跟赋值
为什么不在子类里面自己delete呢?
优雅呗哈哈哈
*/
//作为一个没有拷贝构造函数的基类
class nocpoyable{
public:
nocpoyable(const nocpoyable&) = delete;
void operator=(const nocpoyable&) = delete;
protected: //派生类可以访问,外部不能访问
nocpoyable() = default; //默认实现
~nocpoyable() = default;
};
Logger
#pragma once
#include<string>
#include"nocopyable.hpp"
//模板方法模式
#define LOG_INFO(LogmsgFormat,...)\
do\
{\
Logger &logger = Logger::instance();\
logger.setLogLevel(INFO);\
char buf[1024] = {0};\
snprintf(buf,1024,LogmsgFormat,##__VA_ARGS__);\
logger.log(buf);\
}while(0)
#define LOG_ERROR(LogmsgFormat,...)\
do\
{\
Logger &logger = Logger::instance();\
logger.setLogLevel(ERROR);\
char buf[1024] = {0};\
snprintf(buf,1024,LogmsgFormat,##__VA_ARGS__);\
logger.log(buf);\
}while(0)
//为了防止一些意想不到的错误,都使用do while(0)
//在这里面不能插注释!!!
//斜杠之后连空格都不能有
#define LOG_FATAL(LogmsgFormat,...)\
do{\
Logger &logger = Logger::instance();\
logger.setLogLevel(FATAL);\
char buf[1024] = {0};\
snprintf(buf,1024,LogmsgFormat,##__VA_ARGS__);\
logger.log(buf);\
}while(0)
#ifdef MUDEBUG
#define LOG_DEBUG(LogmsgFormat,...)\
do{\
Logger &logger = Logger::instance();\
logger.setLogLevel(DEBUG);\
char buf[1024] = {0};\
snprintf(buf,1024,LogmsgFormat,##__VA_ARGS__);\
logger.log(buf);\
}while(0)
#else
#define LOG_DEBUG(LogmsgFormat,...)
#endif
//定义日志级别
enum Loglevel{
INFO, //普通信息
ERROR, //错误信息
FATAL, //core信息
DEBUG, //debug信息
};
class Logger:nocpoyable{
public:
//获取单例
static Logger& instance();
//设置日志级别
void setLogLevel(int level);
//写日志
void log(std::string msg);
private:
int loglevel_;
//设置单例
Logger(){}
};
#include"logger.hpp"
#include"timestamp.hpp"
#include<iostream>
//单例模式 懒汉
Logger& Logger::instance(){
static Logger logger;
return logger;
}
//设置日志级别
void Logger::setLogLevel(int level){
loglevel_ = level;
}
//写日志 [级别]:time:msg
void Logger::log(std::string msg){
switch (loglevel_)
{
case INFO:
std::cout<<"[INFO]:";
break;
case ERROR:
std::cout<<"[ERRER]:";
break;
case FATAL:
std::cout<<"[FATAL]:";
break;
case DEBUG:
std::cout<<"[DEBUG]:";
break;
default:
break;
}
timestamp tts;
std::cout<<tts.toString()<<std::endl;
}
Timestamp
#pragma once
#include<iostream>
class timestamp{
public:
timestamp();
//待参数的构造函数都带上了explicit关键字,为什么呢?
//其实有时候代码表现出来的并不是你想的那样
explicit timestamp(int64_t microSecondsSinceEpoch);
static timestamp now();
std::string toString() const;
private:
int64_t microSecondsSinceEpoch_;
};
#include"timestamp.hpp"
#include<time.h>
timestamp::timestamp()
:microSecondsSinceEpoch_(0)
{
}
timestamp::timestamp(int64_t microSecondsSinceEpoch)
:microSecondsSinceEpoch_(microSecondsSinceEpoch)
{
}
timestamp timestamp::now(){
return timestamp(time(NULL));
}
std::string timestamp::toString() const{
char buf[128] = {0};
tm* tm_time = localtime(µSecondsSinceEpoch_);
snprintf(buf,128,"%4d/%02d/%02d %02d:%02d:%02d",
tm_time->tm_year+1900,tm_time->tm_mon+1,tm_time->tm_mday,
tm_time->tm_hour,tm_time->tm_min,tm_time->tm_sec);
return buf;
}
InetAddr
#pragma once
#include<arpa/inet.h>
#include<netinet/in.h>
#include<string>
class InetAddress{
public:
explicit InetAddress(uint16_t port,std::string ip = "127.0.0.1");
explicit InetAddress(const sockaddr_in &addr)
:addr_(addr)
{}
std::string toIp() const;
std::string toIpPort() const;
uint16_t toPort() const;
private:
sockaddr_in addr_;
};
#include"InetAddr.hpp"
#include<string.h>
InetAddress::InetAddress(uint16_t port,std::string ip){
bzero(&addr_,sizeof addr_); //居然还能这样写,以前都不知道
addr_.sin_family = AF_INET;
addr_.sin_port = htons(port); //转换网络字节序
//host to net short
addr_.sin_addr.s_addr = inet_addr(ip.c_str());
}
std::string InetAddress::toIp() const{
char buf[64] = {0};
//这里我也不知道为什么要设置为全局作用域下的
::inet_ntop(AF_INET,&addr_.sin_addr,buf,sizeof(buf));
return buf;
}
std::string InetAddress::toIpPort() const{
char buf[64] = {0};
//这里我也不知道为什么要设置为全局作用域下的
::inet_ntop(AF_INET,&addr_.sin_addr,buf,sizeof(buf));
size_t end = strlen(buf);
uint16_t port = ntohs(addr_.sin_port);
sprintf(buf+end, ":%u", port);
return buf;
}
uint16_t InetAddress::toPort() const{
return ntohs(addr_.sin_port);
}
// #include<iostream>
// int main(){
// InetAddress addr(6666);
// std::cout<<addr.toIpPort()<<std::endl;
// }