move与函数指针的简单使用

std::move()

C++11的标准库 提供了一个非常有用的函数 std::move(),std::move() 函数将一个左值强制转化为右值引用,以用于移动语义。

就是说 std::move(str); 之后原来的值因为变成了右值失效了
但是这样赋值可以避免出现拷贝

#include 
#include 
#include 
using namespace std;

int main()
{
    string str = "hello";
    cout << "before str: " << str << endl;

    vector vstr;
    vstr.emplace_back(std::move(str));
    cout << "after  str: " << str << endl;

    return 0;
}

str 就没有了因为被转移语义了


#include 
#include 
#include 
#include "tinyNetWorkLib.h"
class People{
  using actionEvent = std::function;

public:
  People():value(2){}
  People(int v):value(v){}
  void setCryEvent(actionEvent func){ cry = std::move(func); }
  void setSimleEvent(actionEvent func){ smile = std::move(func);}
  void handleEvent(Timestamp receiverTime){
      if(value >= 0){
        smile(); 
          cout< func = []{
        std:: cout<<"happy"< func2 = []{
        std::cout<<"cry"<

执行结果

happy
2023/08/27 20:49:59

这里函数指针还能用,因为这里转移语义的对象是参数

给出依赖文件的代码Timestamp 复制下来用就好

记得给个#ifndef这里自己

#include 
#include 
#include 
#include 
#include 
#include 
#include  
#include
using namespace std;
class Timestamp
{
public:
    Timestamp()
        : microSecondsSinceEpoch_(0)
    {
    }

    explicit Timestamp(int64_t microSecondsSinceEpoch)
        : microSecondsSinceEpoch_(microSecondsSinceEpoch)
    {
    }

    // 获取当前时间戳
    static Timestamp now();

    //用std::string形式返回,格式[millisec].[microsec]
    std::string toString() const;
    //格式, "%4d年%02d月%02d日 星期%d %02d:%02d:%02d.%06d",时分秒.微秒
    std::string toFormattedString(bool showMicroseconds = false) const;

    //返回当前时间戳的微妙
    int64_t microSecondsSinceEpoch() const { return microSecondsSinceEpoch_; }
    //返回当前时间戳的秒数
    time_t secondsSinceEpoch() const
    { 
        return static_cast(microSecondsSinceEpoch_ / kMicroSecondsPerSecond); 
    }

    // 失效的时间戳,返回一个值为0的Timestamp
    static Timestamp invalid()
    {
        return Timestamp();
    }

    // 1秒=1000*1000微妙
    static const int kMicroSecondsPerSecond = 1000 * 1000;

private:
    // 表示时间戳的微秒数(自epoch开始经历的微妙数)
    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();
}

// 如果是重复定时任务就会对此时间戳进行增加。
inline Timestamp addTime(Timestamp timestamp, double seconds)
{
    // 将延时的秒数转换为微妙
    int64_t delta = static_cast(seconds * Timestamp::kMicroSecondsPerSecond);
    // 返回新增时后的时间戳
    return Timestamp(timestamp.microSecondsSinceEpoch() + delta);
}

Timestamp Timestamp::now()
{
    struct timeval tv;
    // 获取微妙和秒
    // 在x86-64平台gettimeofday()已不是系统调用,不会陷入内核, 多次调用不会有性能损失.
    gettimeofday(&tv, NULL);
    int64_t seconds = tv.tv_sec;
    // 转换为微妙
    return Timestamp(seconds * kMicroSecondsPerSecond + tv.tv_usec);
}

// 2022/08/26 16:29:10
// 20220826 16:29:10.773804
std::string Timestamp::toFormattedString(bool showMicroseconds) const
{
    char buf[64] = {0};
    time_t seconds = static_cast(microSecondsSinceEpoch_ / kMicroSecondsPerSecond);
    // 使用localtime函数将秒数格式化成日历时间
    tm *tm_time = localtime(&seconds);
    if (showMicroseconds)
    {
        int microseconds = static_cast(microSecondsSinceEpoch_ % kMicroSecondsPerSecond);
        snprintf(buf, sizeof(buf), "%4d/%02d/%02d %02d:%02d:%02d.%06d",
                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,
                microseconds);
    }
    else
    {
        snprintf(buf, sizeof(buf), "%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;
}



最后我们给出要给第一个版本的channel

一个文件描述符,发生读事件 写时间 关闭事件 错误事
文件描述符就是一个整形变量
int revents 表示这个文件描述符的心情(状态)
通过位运算表示 和EPOLLINT OUT HUB 先不管

#include 
#include "tinyNetWorkLib.h"
#include 

class Channel{
   using EventCallback = std::function<void()>;
   using ReadEventCallback = std::function<void(Timestamp)>;
public:    
    Channel(int fd):fd_(fd){};

    void setReadCallback(ReadEventCallback cb) { readCallback_ = std::move(cb); }
    void setWriteCallback(EventCallback cb) { writeCallback_ = std::move(cb); }
    void setCloseCallback(EventCallback cb) { closeCallback_ = std::move(cb); }
    void setErrorCallback(EventCallback cb) { errorCallback_ = std::move(cb); } 
    void set_revents(int revt){ revents = revt; }
    void handleWithGuard(Timestamp receiverTime){
        if(revents & EPOLLHUP && !(revents & EPOLLIN)){
            if(closeCallback_){
                 closeCallback_();
            }
        }
        if(revents & EPOLLERR){
            if(errorCallback_){
                errorCallback_();
            }    
        }
        
        if(revents & (EPOLLIN|EPOLLPRI)){
            if(readCallback_){
                 readCallback_(receiverTime);
            }
        }
        if(revents & EPOLLOUT){
            if(writeCallback_){
                 writeCallback_();
            }
        }
    }

private:
   
   ReadEventCallback readCallback_;
   EventCallback writeCallback_;
   EventCallback closeCallback_;
   EventCallback errorCallback_;
   const int fd_;
   int revents;

};

这个和我们People类设计几乎一样除了设计了一点系统知识

#include 
#include 
#include 
#include "tinyNetWorkLib.h"
#include "Channel.h"
class People{
  using actionEvent = std::function;

public:
  People():value(2){}
  People(int v):value(v){}
  void setCryEvent(actionEvent func){ cry = std::move(func); }
  void setSimleEvent(actionEvent func){ smile = std::move(func);}
  void handleEvent(Timestamp receiverTime){
      if(value >= 0){
        smile(); 
          cout< func = []{
        std:: cout<<"happy"< func2 = []{
        std::cout<<"cry"<
执行结果
happy

你可能感兴趣的:(网络编程,c++,开发语言)