std::move()
C++11的标准库 提供了一个非常有用的函数 std::move(),std::move() 函数将一个左值强制转化为右值引用,以用于移动语义。
就是说 std::move(str); 之后原来的值因为变成了右值失效了
但是这样赋值可以避免出现拷贝
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
string str = "hello";
cout << "before str: " << str << endl;
vector<string> vstr;
vstr.emplace_back(std::move(str));
cout << "after str: " << str << endl;
return 0;
}
str 就没有了因为被转移语义了
#include <iostream>
#include <functional>
#include <utility>
#include "tinyNetWorkLib.h"
class People{
using actionEvent = std::function<void()>;
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<<receiverTime.toFormattedString()<<endl;
}else{
cry();
cout<<receiverTime.toFormattedString()<<endl;
}
}
private:
actionEvent cry;
actionEvent smile;
int value;
};
int main()
{
std::function<void()> func = []{
std:: cout<<"happy"<<std::endl;
};
std::function<void()> func2 = []{
std::cout<<"cry"<<std::endl;
};
People peo;
peo.setCryEvent(func2);
peo.setSimleEvent(func);
peo.handleEvent(Timestamp ::now());
// std::cout << "Hello world" << std::endl;
return 0;
}
执行结果
happy
2023/08/27 20:49:59
这里函数指针还能用,因为这里转移语义的对象是参数
给出依赖文件的代码Timestamp 复制下来用就好
记得给个#ifndef这里自己
#include <functional>
#include <set>
#include <sys/time.h>
#include <sys/eventfd.h>
#include <fcntl.h>
#include <unistd.h>
#include <mutex>
#include<unordered_map>
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<time_t>(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<int64_t>(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<time_t>(microSecondsSinceEpoch_ / kMicroSecondsPerSecond);
// 使用localtime函数将秒数格式化成日历时间
tm *tm_time = localtime(&seconds);
if (showMicroseconds)
{
int microseconds = static_cast<int>(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 先不管文章来源:https://www.toymoban.com/news/detail-677446.html
#include <functional>
#include "tinyNetWorkLib.h"
#include <sys/epoll.h>
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类设计几乎一样除了设计了一点系统知识文章来源地址https://www.toymoban.com/news/detail-677446.html
#include <iostream>
#include <functional>
#include <utility>
#include "tinyNetWorkLib.h"
#include "Channel.h"
class People{
using actionEvent = std::function<void()>;
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<<receiverTime.toFormattedString()<<endl;
}else{
cry();
cout<<receiverTime.toFormattedString()<<endl;
}
}
int set_value(int v){value = v;}
private:
actionEvent cry;
actionEvent smile;
int value;
};
int main()
{
std::function<void()> func = []{
std:: cout<<"happy"<<std::endl;
};
std::function<void()> func2 = []{
std::cout<<"cry"<<std::endl;
};
// People peo;
// peo.setCryEvent(func2);
// peo.setSimleEvent(func);
// peo.handleEvent(Timestamp ::now());
// std::cout << "Hello world" << std::endl;
// func();
Channel chanel(1);
chanel.set_revents(EPOLLOUT);
chanel.setWriteCallback(func);
chanel.handleWithGuard(Timestamp::now());
return 0;
}
执行结果
happy
到了这里,关于move与函数指针的简单使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!