Sylar C++高性能服务器学习记录03 【配置系统-知识储备篇】

Sylar C++高性能服务器学习记录03 【配置系统-知识储备篇】

早在19年5月就在某站上看到sylar的视频了,一直认为这是一个非常不错的视频。 由于本人一直是自学编程,基础不扎实,也没有任何人的督促,没能坚持下去。 每每想起倍感惋惜,遂提笔再续前缘。

为了能更好的看懂sylar,本套笔记会分两步走,每个系统都会分为两篇博客。 分别是【知识储备篇】和【代码分析篇】 (ps:纯粹做笔记的形式给自己记录下,欢迎大家评论,不足之处请多多赐教) QQ交流群:957100923 B站视频:https://b23.tv/YusP39I

配置系统-知识储备

知识点01 (boost库的安装)

boost是一个非常强大的库,sylar配置系统中用到了boost库的类型转换功能,所以我们需要提前安装一下:

去官网下载库压缩包文件 boost_x_x_x.tar.gz

//如果你是在服务器上操作的,可以在网页中鼠标移动到对应压缩包上右键复制下载地址然后使用

wget https://sourceforge.net/projects/boost/files/boost/1.61.0/boost_1_61_0.tar.gz

//解压:

tar -zxvf boost_x_x_x.tar.gz

//进入解压后的文件夹:

cd boost_x_x_x

//运行脚本,如果没有权限请先赋权:chmod +x ./bootstrap.sh

./bootstrap.sh

//运行脚本:.

/b2 install

这样你的boost库安装好了,速度取决于你的机器好坏,总之挺久的。 当然你可以yum安装

yum install -y boost boost-devel

以下可以测试以下你的boost是否安装成功

#include

#include

int main(int argc,char** argv){

cout << BOOST_VERSION <

cout << BOOST_LIB_VERSION<

cout << BOOST_STDLIB <

cout <

cout << BOOST_COMPILER<

}

lexical_cast的作用 lexical_cast使用统一的接口实现字符串与目标类型之间的转换。

#include "iostream"

#include "boost/lexical_cast.hpp" // 需要包含的头文件

int main(){

char* p="32768";

int i=0;

// 将字符串转化为整数

i=boost::lexical_cast(p);

std::cout << i << std::endl;

return i;

}

知识点02 (yaml-cpp的安装与使用)

由于我们的配置系统是基于yaml的,所以我们需要安装对应c++的库。

//我这里指定了 Tag 因为我的cmake用的 2.8的

git clone -b yaml-cpp-0.6.0 --single-branch https://github.com/jbeder/yaml-cpp.git

cd yaml-cpp

mkdir build

cd build

cmake -DBUILD_SHARED_LIBS=ON .. //-DBUILD_SHARED_LIBS=ON 启用动态库

make -j

make install

接下来是CMakeLists的配置这里直接拿sylar的配置

cmake_minimum_required(VERSION 2.8)

project(sylar)

include (cmake/utils.cmake)

set(CMAKE_VERBOSE_MAKEFILE ON)

set(CMAKE_CXX_FLAGS "$ENV{CXXFLAGS} -rdynamic -O0 -ggdb -std=c++11 -Wall -Wno-deprecated -Werror -Wno-unused-function -Wno-builtin-macro-redefined")

include_directories(.)

include_directories(/apps/sylar/include)

link_directories(/apps/sylar/lib)

find_library(YAMLCPP yaml-cpp)

add_executable(test_config tests/test_config.cc)

target_link_libraries(test_config ${YAMLCPP})

SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

接下来我们创建一个test.yaml文件用来测试

name: XYZ

sex: male

age: 30

system:

port: 0

value: 0

int_vec: [10, 20]

接下来我们在 test_config.cc中做测试

#include

#include

int main(int argc,char** argv){

YAML::Node node = YAML::LoadFile("/apps/sylar/bin/conf/test.yaml");

std::cout << node["name"].as() << std::endl;

std::cout << node["sex"].as() << std::endl;

std::cout << node["age"].as() << std::endl;//18

std::cout << node["system"]["port"].as() << std::endl;

std::cout << node["system"]["value"].as() << std::endl;

for(auto it = node["system"]["int_vec"].begin(); it != node["system"]["int_vec"].end(); ++it){

std::cout << *it <<“ ”;

}

std::cout << std::endl;

return 0;

}

以下是输出:

XYZ

male

30

0

0

10 20

此时证明yaml-cpp已经可以正常使用了

知识点03 (find_first_not_of 与 find_last_not_of 的使用)

1.find_first_not_of()函数 正向查找在原字符串中第一个与指定字符串(或字符)中的任一字符都不匹配的字符,返回它的位置。若查找失败,则返回npos。(npos定义为保证大于任何有效下标的值。)

#include

#include

int main(){

std::string prefix="xyz";

std::string str="abcd";

if(prefix.find_first_not_of(str)!=std::string::npos){

std::cout << prefix << " is not in " << str;

}

return 0;

}

2.find_last_not_of()函数 正向查找在原字符串中最后一个与指定字符串(或字符)中的任一字符都不匹配的字符,返回它的位置。若查找失败,则返回npos。(npos定义为保证大于任何有效下标的值。)

#include

#include

int main(){

std::string prefix="xyz";

std::string str="abcd";

if(prefix.find_last_not_of(str)!=std::string::npos){

std::cout << prefix << " is not in " << str;

}

return 0;

}

知识点04 (模板泛化,模板全特化,模板偏特化)

1.什么是模板类? 在 C++ 中,模板类是一种通用的类模板,允许我们定义一种可以用于多种数据类型的类。通过使用模板类,我们可以在不重复编写代码的情况下创建适用于不同类型的类实例。

2.模板类的(泛化,全特化,偏特化)

//1.泛化的Test类模板

template

class Test {

Test(){cout << "泛化版本的构造函数" << endl;}

void Func(){cout << "泛化版本" << endl;}

};

//2.全特化的Test类模板

//当T和U这两个类型模板参数都为int类型时,做一个特化版本

//全特化:就是所有类型模板参数(这里T 和 U),都用具体类型代表

template<> //全特化:所有类型模板参数都用具体类型代表,所以这里的template后面的<>里就为空

class Test //上边的T绑定到这里的第一个int,上边的U绑定到这里的第二个int

{

Test(){cout << "int , int的特化版本构造函数" << endl;}

//可以该特化版本进行单独处理

void Func(){cout << "int , int的特化版本" << endl;}

};

template<> //全特化:所有类型模板参数都用具体类型代表,所以这里的template后面的<>里就为空

class Test //上边的T绑定到这里的第一个int,上边的U绑定到这里的第二个int

{

Test(){cout << "double , int的特化版本构造函数" << endl;}

//可以该特化版本进行单独处理

void Func(){cout << "double , int的特化版本" << endl;}

};

//3.偏特化的类模板

//从参数数量上进行偏特化,现在绑定两个类型模板参数

template //留一个U类型模板参数

class Test{

void Func() { cout << "偏特化int ,U, double版本" << endl; }

};

3.模板函数的(泛化,全特化)

//泛化版本

template

void Func(const T& a, const U& b){

cout << "Func()泛化版本" << endl;

cout << a << " " << b << endl;

}

//全特化版本

template<>

void Func(const int& a, const double& b){

cout << "Func()int,double 全特化版本" << endl;

cout << a << " " << b << endl;

}

//偏特化版本(不支持!!!)

int main(){

const char* p = "I Love China";

int a = 12;

Func(p, a);

//全特化函数模板实际上等价于实例化一个函数模板,并不是等级一个函数重载

Func(15, 25.3); //特化版本

return 0;

}

4.模板类作为函数返回对象时需要 typename 修饰

templete

typename Test func(){

return new Test();

}

5.模板类作为类型定义时需要 typename 修饰

typename Test t = new Test();

模板特化相关知识点非常多,这里只是做简单了解,需要深入了解可以自行学习。

知识点05 (dynamic_pointer_cast)

std::dynamic_pointer_cast<目标类型>(被转换智能指针) 接受一个被转换的智能指针和目标类型的指针类型作为参数,并返回一个新的智能指针。 dynamic_pointer_cast只适用于std::shared_ptr和std::weak_ptr类型的智能指针,用于进行智能指针的动态类型转换。

#include

#include

struct Base {

virtual ~Base() {}

};

struct Derived : public Base {

void foo() {

std::cout << "Derived::foo() called" << std::endl;

}

};

int main() {

std::shared_ptr basePtr = std::make_shared();

std::shared_ptr derivedPtr = std::dynamic_pointer_cast(basePtr);

if (derivedPtr) {

derivedPtr->foo();

} else {

std::cout << "Failed to perform dynamic cast" << std::endl;

}

return 0;

}

知识点06 (::tolower 与 ::toupper)

#include

int main(int argc, char** argv) {

string str="abcDEF";

for(int i=0;i

str[i]=::tolower(str[i]);

}

std::cout<

for(int i=0;i

str[i]=::toupper(str[i]);

}

std::cout<

return 0;

}

知识点07 (std::transform)

使用该函数,必须添加包含算法库“algorithm”。 它接受四个参数: 1:输入范围的起始迭代器。 2:输入范围的结束迭代器。 3:输出范围的起始迭代器。 4:一个一元操作函数,用于对输入范围内的每个元素进行处理。

std::vector nums = {1, 2, 3, 4, 5};

std::vector result(nums.size());

std::transform(nums.begin(), nums.end(), result.begin(), [](int x) { return x * 2; });

//结合 ::tolower

std::string str="aBcDef";

std::transform(str.begin(), str.end(), str.begin(), ::tolower);

std::cout << str << std::endl; //abcdef

知识点08 (仿函数)

仿函数是一个类或结构体,它重载了operator()运算符,使其可以像函数一样被调用。 仿函数的实例可以像函数指针一样传递给STL算法或容器的操作,从而实现自定义行为。 比如下面这个,Less是一个仿函数,它接受两个参数并返回"<"比较的结果。

template

class Less {

public:

bool operator()(const T& x, const T& y){

return x < y;

}

};

接下来可以看下【配置系统-代码分析篇】 求关注:持续更新… QQ交流群:957100923

相关推荐

【就业招聘月】现场宣讲 | 11月25日 | 中国人民解放军32069部队
水表号怎么查用户号,水表上怎么看缴费户号的9位数
s365国网公司健步走app

水表号怎么查用户号,水表上怎么看缴费户号的9位数

📅 08-07 👍 978
有哪些堪称PPT神器插件?用好这10款,让你像开挂了一样设计PPT!