相关文章推荐
在平时的开发中,我们经常会遇到很多和时间有关系的代码,因此在muduo库中,作者也设计了Timestamp类,来对时间的使用
// Use of this source code is governed by a BSD-style license
// that can be found in the License file.
// Author: Shuo Chen (chenshuo at chenshuo dot com)
#ifndef MUDUO_BASE_TIMESTAMP_H
#define MUDUO_BASE_TIMESTAMP_H
#include "muduo/base/copyable.h"
#include "muduo/base/Types.h"
#include <boost/operators.hpp>
namespace muduo
/// Time stamp in UTC, in microseconds resolution.
/// This class is immutable.
/// It's recommended to pass it by value, since it's passed in register on x64.
class Timestamp : public muduo::copyable,
                  public boost::equality_comparable<Timestamp>,
                  public boost::less_than_comparable<Timestamp>
 public:
  /// Constucts an invalid Timestamp.
  Timestamp()
    : microSecondsSinceEpoch_(0)
  /// Constucts a Timestamp at specific time
  /// @param microSecondsSinceEpoch
  explicit Timestamp(int64_t microSecondsSinceEpochArg)
    : microSecondsSinceEpoch_(microSecondsSinceEpochArg)
  void swap(Timestamp& that)
    std::swap(microSecondsSinceEpoch_, that.microSecondsSinceEpoch_);
  // default copy/assignment/dtor are Okay
  string toString() const;
  string toFormattedString(bool showMicroseconds = true) const;
  bool valid() const { return microSecondsSinceEpoch_ > 0; }
  // for internal usage.
  int64_t microSecondsSinceEpoch() const { return microSecondsSinceEpoch_; }
  time_t secondsSinceEpoch() const
  { return static_cast<time_t>(microSecondsSinceEpoch_ / kMicroSecondsPerSecond); }
  /// Get time of now.
  static Timestamp now();
  static Timestamp invalid()
    return Timestamp();
  static Timestamp fromUnixTime(time_t t)
    return fromUnixTime(t, 0);
  static Timestamp fromUnixTime(time_t t, int microseconds)
    return Timestamp(static_cast<int64_t>(t) * kMicroSecondsPerSecond + microseconds);
  static const int kMicroSecondsPerSecond = 1000 * 1000;
 private:
  int64_t microSecondsSinceEpoch_;
inline bool operator<(Timestamp lhs, Timestamp rhs)
  return lhs.microSecondsSinceEpoch() < rhs.microSecondsSinceEpoch();
inline bool operator==(Timestamp lhs, Timestamp rhs)
  return lhs.microSecondsSinceEpoch() == rhs.microSecondsSinceEpoch();
/// Gets time difference of two timestamps, result in seconds.
/// @param high, low
/// @return (high-low) in seconds
/// @c double has 52-bit precision, enough for one-microsecond
/// resolution for next 100 years.
inline double timeDifference(Timestamp high, Timestamp low)
  int64_t diff = high.microSecondsSinceEpoch() - low.microSecondsSinceEpoch();
  return static_cast<double>(diff) / Timestamp::kMicroSecondsPerSecond;
/// Add @c seconds to given timestamp.
/// @return timestamp+seconds as Timestamp
inline Timestamp addTime(Timestamp timestamp, double seconds)
  int64_t delta = static_cast<int64_t>(seconds * Timestamp::kMicroSecondsPerSecond);
  return Timestamp(timestamp.microSecondsSinceEpoch() + delta);
}  // namespace muduo
#endif  // MUDUO_BASE_TIMESTAMP_H
通过头文件我们能够学习的知识点:
  • 命名空间 namesapce
    在c++开发中如果我们需要封装自己的库给别人用,一般最后在自己的模块中加上命名空间,这样可以防止和比人的模块因为重名而导致的冲突

  • Timestamp类继承了muduo::copyable和 boost::equality_comparable ,boost::less_than_comparable
    其实在我们学习c++的过程中有很多的大神和书籍都反复强调我们在c++中不应该使用多继承,但是我们却发现muduo的Timestamp类继承了三个类,但是当我查看muduo继承的这三个基类发现:

    • muduo::copyable的代码:

      #ifndef MUDUO_BASE_COPYABLE_H
      #define MUDUO_BASE_COPYABLE_H
      namespace muduo
      /// A tag class emphasises the objects are copyable.
      /// The empty base class optimization applies.
      /// Any derived class of copyable should be a value type.
      class copyable
       protected:
        copyable() = default;
        ~copyable() = default;
      }  // namespace muduo
      #endif  // MUDUO_BASE_COPYABLE_H
      

      通过代码我们会发现,copyable类什么也没有做,子类继承也没有任何的用处,查看做的注释:标签类强调对象是可复制的。应用空基类优化。任何可复制的派生类都应该是值类型。我们大概明白了这个类其实就是一个空类,表明这个类的是否可以被继承,如果子类继承了该类就说明这个类时可以拷贝的,这样做的好处就是虽然子类继承了他,但是并不会对子类有任何的影响,,但是使用的人却可以很直白的知道子类是否可以拷贝。这种类我们把它称之为标签类,通过该类我们可以知道被他继承的类是不是可以有这样的操作,Timestamp继承了copyable,那就说明Timestamp是可以拷贝的。查看muduo库的代码,发现类似于copyable的类还有noncopyable。

    • boost::equality_comparable和boost::less_than_comparable

      查看boost库发现这两个类其实是两个是用来比较的, 类只要实现对operator==就会自动实现!=

      less_than_comparable类 只要实现operator<,可自动实现>、<=、>=,后面有机会再看看这两个类的实现。

  • explicit 关键字

    explicit Timestamp(int64_t microSecondsSinceEpochArg)
        : microSecondsSinceEpoch_(microSecondsSinceEpochArg)
    

    explicit关键字的作用就是防止编译器进行的隐士构造,从而出现我们预期之外的执行结果。explicit能防止的只是从int64_t到Timestamp的隐式构造 Timestamp t = 12这种事错误的,但是Timestamp t(12)正确。

  • 成员函数的设计:

    通过观察可以发现Timestamp类有几个函数并没有实现为成员函数,这几个函数都是需要两个Timestamp去做一些计算的操作,如果是成员函数,那么相加和相减这种操作对应的调用改方法的对象的值是会被修改的,但这正不是我们想看到,所以作者把他设计为普通的函数,返回一个Timestamp对象,这代表着一种编程的思想和原则。需要我们在设计一个类的时候考虑好。

  • const关键字的使用

    toString、toFormattedString、valid这三个函数是被设计为const函数,使用了const关键字,函数内所有对象成员变量是只读,这样可防止误改,虽然不加const关键字也不一定会错,但是如果加了const关键字就说明该函数是一个读函数,而不会有写的操作,这也是一种编程的原则和思想吧,值得学习和借鉴。

  • static成员和函数:

    now、invalid、fromUnixTime,这三个函数如果不是static函数那么我们在使用Timestamp类的时候如果需要获取一个当前的时间,那么还得先定义一个Timestamp对象,然后通过对象获取,这样就是多此一举。查看这几个static函数的实现发现静态函数是没有对静态成员有写的操作,所以就没有上锁的操作,如果有静态函数的实现有对static成员的写操作,那么就会有性能上的下降,这时就应该考虑设计是否合理。kMicroSecondsPerSecond这是一个static变量,该变量是一个在Timestamp中频繁使用且不会有写的常量,所以设计为静态。

  • 成员的命名:

    • k开头的变量说明是一个常量,只是Google的命名规范,可以借鉴
  • static_assert断言的使用:

    static_assert函数是boost提供的一个函数,该函数可以实现在编译期间断言的功能,如果在编译期间static_assert内语句不为真,那么就不能编译通过

通过对muduo库Timestamp类我们可以学习到知识点有:

  1. 命名空间 namesapce
  2. 标签类的使用
  3. boost库中equality_comparable和less_than_comparable类
  4. explicit关键字
  5. 类涉及到函数的设计
  6. const成员函数
  7. static函数和成员的设计
  8. boost static_assert在编译期实现断言
  9. const变量使用k开头命名
在平时的开发中,我们经常会遇到很多和时间有关系的代码,因此在muduo库中,作者也设计了Timestamp类,来对时间的使用头文件:// Use of this source code is governed by a BSD-style license// that can be found in the License file.//// Author: Shuo Chen (che...
总结之前项目出现得问题,第一次在linux上运行项目,服务器运行成功之后访问项目,别得都好好得,就登陆时候得验证码获得不了,使用谷歌浏览器的Network监测到请求已经发过去了,然后直接调用获取验证码的方法报错:“java.lang.NoClassDefFoundError:could not initialise class sun.awt.X11FontManager”。 然后又去百度,什么...
1. 时间戳(Timestamp)类图 一个常量kMicroSecondsPerSecond,表示每秒所对应的微秒数,成员变量microSecondsSinceEpoch_表示到1970-01-01 00:00:00 UTC的微秒数 2. 关于使用时间的API 先看三个时间结构体: struct timeval long tv_sec;//秒 64位 8字节 long tv_usec;//微秒 struct tm int t
MutexLock私有成员: Phread_mutex_t mutex_; //互斥变量 pid_t holder; //用来表示给互斥量上锁线程的tidMutexLock() ~MutexLock() isLockByThisThread() -> bool 用来检查给互斥量上锁的是否为当前线程 assertLocked() lock() //加锁,调用assignHo
日历时间:以年月日星期的方式表示,通常作为日志输出 绝对时间:表示为从1970年1月1日以来的秒数 clock时间:这是一个相对时间,表示从开启进程到此时的CPU tick数 关于时区,由于世界不同的地区可能处于不同的时区,通常需要基于世界标准时间(UTC)进行时区转换,比如,中国内地的时间与UTC的时差为+8,也就是UTC+8。美国是UTC-5。 而在muduo中,关于时间与日期的表示,有 Date类,用来表示年月日的日历时间 TimeStamp类,用来表示
本文是笔者通过学习Muduo多线程网络程序开发日志模块所做出的总结,文中大量引用了陈硕所著的《Linux多线程服务端编程:使用muduo C++网络》以及luotuo44《muduo日志学习》博客中的内容。此外,本文代码取自analogous_love的开源项目flamingo,笔者在此一并表示感谢。 由于笔者接触多线程开发时间较短,文中所书难免有误,还请多多包涵~ 日志是服务器端...
Timestamp.h头文件,定义了Timestamp类中的相关函数和变量 #ifndef MUDUO_BASE_TIMESTAMP_H //预定义 #define MUDUO_BASE_TIMESTAMP_H #include <muduo/base/copyable.h> //头文件 copyable.h是一个空实现,仅为了做标识 #include <muduo/base/Types.h> //基本类型的声明 #include <boost/operators
Boost是一个跨平台的C++程序,提供了许多常用的C++工具和类。它涵盖了数学、字符串处理、文件系统、网络编程等多个方面。 Muduo是一个轻量级的C++网络,主要用于服务器端开发。它提供了异步网络、事件驱动、高性能等特性。 总的来说,Boost提供了更广泛的C++工具和类,而Muduo专注于网络编程。
 
推荐文章