当前位置: 首页 > news >正文

网站维护的内容seo网站关键词优化哪家好

网站维护的内容,seo网站关键词优化哪家好,挂别人公司做网站可以吗,国内做网站哪家公司好文章目录 p9#xff1a;配置模块搭建一、ConfigvarBase二、ConfigVar三、Config四、小结 p10#xff1a;YAML的使用一、安装yaml-cpp二、使用yaml-cpp三、代码解析 P11#xff1a;YAML与日志的整合一、方法函数二、代码调试三、test_config结果四、小结 p9#xff1a;配置模… 文章目录 p9配置模块搭建一、ConfigvarBase二、ConfigVar三、Config四、小结 p10YAML的使用一、安装yaml-cpp二、使用yaml-cpp三、代码解析 P11YAML与日志的整合一、方法函数二、代码调试三、test_config结果四、小结 p9配置模块搭建 ​ 很长时间没写了又把上次的断点p9重新看了一次。 ​ 前面几个章节已经搭建好了日志系统的基本架构从第九节开始搭建配置模块。该模块的主要用于定义/声明配置项并且从配置文件中加载用户的配置。整个配置模块的目标就是与日志模块相结合当配置文件相应参数做出改变时能够通过回调函数改变相应的参数。 ​ 配置模块包含3个类 ConfigvarBase作为配置基类放置一些公用的属性ConfigVar配置参数模板子类主要功能实现string和T类型之间的相互转化ConfigConfigVar的管理类 一、ConfigvarBase ​ 两个成员变量m_name、m_description分别定义配置参数的名称和描述纯虚函数toString和fromString由子类ConfigVar实现。 class ConfigvarBase { public:typedef std::shared_ptrConfigvarBase ptr;ConfigvarBase(const std::string name, const std::string description ):m_name(name),m_description(description) {} // 构造函数virtual ~ConfigvarBase() {} // 析构函数const std::string getName() const { return m_name; } // 返回配置参数名称const std::string getDescription() const { return m_description; } // 返回配置参数描述virtual std::string toString() 0; // 转换成字符串virtual bool fromString(const std::string val) 0; // 从字符串初始化值 protected:std::string m_name; // 配置参数的名称std::string m_description; // 配置参数的描述 };二、ConfigVar ​ m_val是参数名对应的参数值。从构造函数可以看出目前的配置类主要包括配置名称、参数值以及配置描述3个变量。toString和fromString成员函数主要使用lexical_cast进行了类型转换如果转换失败会打印出日志、异常以及值的类型。 templateclass T class ConfigVar : public ConfigvarBase { public:typedef std::shared_ptrConfigVar ptr;ConfigVar(const std::string name, const T default_value, const std::string description ) // 初始化配置名称、参数值以及参数描述:ConfigvarBase(name,description),m_val(default_value) {}std::string toString() override { // 将参数值转换为string类型try {return boost::lexical_caststd::string(m_val);} catch(std::exception e) {SYLAR_LOG_ERROR(SYLAR_LOG_ROOT()) ConfigVar::toString exception e.what() convert: typeid(m_val).name() to string;}return ;}bool fromString(const std::string val) override { // 从string转换为参数值try {m_val boost::lexical_castT(val);} catch (std::exception e) {SYLAR_LOG_ERROR(SYLAR_LOG_ROOT()) ConfigVar::fromString exception e.what() convert: string to typeid(m_val).name();}return false;}const T getValue() const { return m_val; }void setValue(const T v) { m_val v; }private:T m_val; };三、Config ​ Config是配置管理类成员变量s_datas使用static是为了保证初始化顺序。成员函数Lookup则是查找目标配置项。 class Config { public:typedef std::mapstd::string, ConfigvarBase::ptr ConfigVarMap;// 定义如果没有则初始化templateclass Tstatic typename ConfigVarT::ptr Lookup(const std::string name,const T default_value, const std::string description ) { // typename这里是告诉编译器::后面是类型而不是变量名auto tmp LookupT(name); if(tmp) {SYLAR_LOG_INFO(SYLAR_LOG_ROOT()) Lookup nmae name exists;}// 发现异常if(name.find_first_not_of(abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ._012345678) ! std::string::npos) { // []SYLAR_LOG_ERROR(SYLAR_LOG_ROOT()) Lookup name invalid name;throw std::invalid_argument(name);}// 无异常则定义typename ConfigVarT::ptr v(new ConfigVarT(name, default_value, description));s_datas[name] v;return v;}// 查找templateclass Tstatic typename ConfigVarT::ptr Lookup(const std::string name) {auto it s_datas.find(name);if(it s_datas.end()) { // 未找到return nullptr;}return std::dynamic_pointer_castConfigVarT(it-second); // 找到转换成智能指针} private:static ConfigVarMap s_datas; }; 四、小结 ​ 以上就是整个配置类的一个初步架构下面编写测试文件进行测试。 在tests文件夹创建test_config.cc #include iostream #include ../sylar/log.h #include ../sylar/util.h #include../sylar/config.hsylar::ConfigVarint::ptr g_int_value_config sylar::Config::Lookup(system.port, (int)8080, system port);// sylar::ConfigVarfloat::ptr g_float_value_config // sylar::Config::Lookup(system.value, (float)10.2f, system value);int main(int argc, char** argv) {std::cout g_int_value_config-getValue() std::endl;SYLAR_LOG_INFO(SYLAR_LOG_ROOT());SYLAR_LOG_INFO(SYLAR_LOG_ROOT()) g_int_value_config-getValue(); // SYLAR_LOG_INFO刚刚报错是因为我在定义时getRoot没有加()进行调用SYLAR_LOG_INFO(SYLAR_LOG_ROOT()) g_int_value_config-toString();// SYLAR_LOG_INFO(SYLAR_LOG_ROOT()) g_float_value_config-getValue(); // SYLAR_LOG_INFO(SYLAR_LOG_ROOT()) g_float_value_config-toString();return 0; }在CMakeLists.txt文件添加下列内容 cmake_minimum_required(VERSION 2.8) project(sylar)set(CMAKE_VERBOSE_MAKEFILE ON) set(CMAKE_CXX_FLAGS $ENV{CXXFLAGS} -rdynamic -O0 -g -stdc11 -Wall -Wno-deprecated -Werror -Wno-unused-function)set(LIB_SRCsylar/log.ccsylar/util.ccsylar/config.cc)add_library(sylar SHARED ${LIB_SRC}) #add_library(sylar_static STATIC ${LIB_SRC}) #SET_TARGET_PROPERTIES(sylar_static PROPERTIES OUTPUT_NAME sylar)add_executable(test tests/test.cc) add_dependencies(test sylar) target_link_libraries(test sylar)add_executable(test_config tests/test_config.cc) add_dependencies(test_config sylar) target_link_libraries(test_config sylar)SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib) 终端输入make编译 终端输入bin/test_config运行生成的可执行文件 p10YAML的使用 ​ 本节内容主要是通过使用yaml-cpp库从yaml文件中读取配置信息下面内容主要记录配置yaml的步骤以及对sylar使用yaml-cpp里面的方法进行一个简单解释。 一、安装yaml-cpp 从github上克隆仓库git clone https://github.com/jbeder/yaml-cpp.git结果如下图所示我是把克隆下来的仓库放在了项目外面因为我们使用时不需要用到整个仓库所有的东西。 在克隆下来的仓库里面创建一个build文件夹终端输入cd yaml-cpp 、mkdir build 进入创建的build文件夹。输入cmake -DBUILD_SHARED_LIBSON ..,注意后面两个点不能忽略。然后得到如下内容其中画横线的3个so文件就是我们需要的。 最后开始安装输入下列命令 make sudo make install二、使用yaml-cpp ​ sylar这节演示的测试用例就是把一个yaml文件的内容遍历到控制台上一步我们已经完成了yaml-cpp的安装下面还需要项目文件了进行一些配置。 按照sylar的目录结构在bin文件下创建一个conf文件夹然后再创建一个log.yml文件内容如下 logs:- name: rootlevel: infoformatter: %d%T%m%nappenders:- type: FileLogAppenderfile: /root/Web-learning/sylar/root.txt- type: StdoutLogAppender- name: systemlevel: infoformatter: %d%T%m%nappenders:- type: FileLogAppenderfile: /root/Web-learning/sylar/system.txt- type: StdoutLogAppender 进入我们刚才克隆下来编译后的yaml-cpp首先在build文件夹找到下图3个文件 把它们复制到sylar项目lib文件夹下如下图所示 然后再回到yaml-cpp文件夹找到里面的一个include文件夹也将它复制到sylar中如下 进入CMakeLists.txt,添加一些配置文件每一句我都写了注释如下 cmake_minimum_required(VERSION 2.8) project(sylar)set(CMAKE_VERBOSE_MAKEFILE ON) set(CMAKE_CXX_FLAGS $ENV{CXXFLAGS} -rdynamic -O0 -g -stdc11 -Wall -Wno-deprecated -Werror -Wno-unused-function)include_directories(.) # 这个不知道什么意思 include_directories(/root/Web-learning/sylar/include) # 这个路径需要按照你自己主机上include放的位置 link_directories(/root/Web-learning/sylar/lib) # 同样根据自己主机lib的位置必须保证该lib文件夹下有你刚刚复制的3个yaml-cpp的so库find_library(YAMLCPP libyaml-cpp.a) # 待set(LIB_SRCsylar/log.ccsylar/util.ccsylar/config.cc)add_library(sylar SHARED ${LIB_SRC}) #add_library(sylar_static STATIC ${LIB_SRC}) #SET_TARGET_PROPERTIES(sylar_static PROPERTIES OUTPUT_NAME sylar)add_executable(test tests/test.cc) add_dependencies(test sylar) target_link_libraries(test sylar)add_executable(test_config tests/test_config.cc) add_dependencies(test_config sylar) target_link_libraries(test_config sylar -L/root/Web-learning/sylar/lib -lyaml-cpp) # 待SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib) 书写测试用例进入test_config.cc #include iostream #include ../sylar/log.h #include ../sylar/util.h #include../sylar/config.h #includeyaml-cpp/yaml.hsylar::ConfigVarint::ptr g_int_value_config sylar::Config::Lookup(system.port, (int)8080, system port);// sylar::ConfigVarfloat::ptr g_float_value_config // sylar::Config::Lookup(system.value, (float)10.2f, system value);void print_yaml(const YAML::Node node, int level) {if(node.IsScalar()) {SYLAR_LOG_INFO(SYLAR_LOG_ROOT()) std::string(level * 4, ) node.Scalar() - node.Type() - level;} else if(node.IsNull()) {SYLAR_LOG_INFO(SYLAR_LOG_ROOT()) std::string(level * 4, ) NULL - node.Type() - level;} else if(node.IsMap()) {for(auto it node.begin(); it ! node.end(); it) {SYLAR_LOG_INFO(SYLAR_LOG_ROOT()) std::string(level * 4, ) it-first - it-second.Type() - level;print_yaml(it-second, level 1);}} else if(node.IsSequence()) {for(size_t i 0; i node.size(); i) {SYLAR_LOG_INFO(SYLAR_LOG_ROOT()) std::string(level * 4, ) i - node[i].Type() - level;print_yaml(node[i], level 1);}} }void test_yaml() {YAML::Node root YAML::LoadFile(/root/Web-learning/sylar/bin/conf/log.yml);print_yaml(root, 0); } int main(int argc, char** argv) {// std::cout g_int_value_config-getValue() std::endl;SYLAR_LOG_INFO(SYLAR_LOG_ROOT());SYLAR_LOG_INFO(SYLAR_LOG_ROOT()) g_int_value_config-getValue(); // SYLAR_LOG_INFO刚刚报错是因为我在定义时getRoot没有加()进行调用SYLAR_LOG_INFO(SYLAR_LOG_ROOT()) g_int_value_config-toString();// SYLAR_LOG_INFO(SYLAR_LOG_ROOT()) g_float_value_config-getValue(); // SYLAR_LOG_INFO(SYLAR_LOG_ROOT()) g_float_value_config-toString();test_yaml();return 0; }结果展示 三、代码解析 ​ 简单介绍一下本节中使用的YAML里面的一些方法函数 YAML::LoadFile()接收一个文件路径载入目标yml文件 node.IsScalar()判断当前是否为标量可以理解为常量从如下YAMLtype.h中,可以看到作者定义了5中不同类型当我们读取自定义yml文件时就会根据当前遍历的值去判断应该做什么操作。 node.Type()对应上诉NodeType中的下标值不过按照sylar的测试用例结果感觉有点不对比如对于log.yml中logs的输出logs作为一个map,它的下标应该对应4然而结果node.Type()输出的是3。我理解错了看最后一点 std::string(level * 4, ’ )根据level的不同在输出前面加空格的数量美化结果输出 对于node.Type()我刚刚提出的疑问输出的IsMap是我在代码添加判断里加的有一个问题就是当遇到Map时会进行遍历而遍历的内容可能会出现其它类型比如Scalar或则Sequence然而我却在该Map的条件判断里打印输出都加上了IsMap所以造成输出的type值与IsMap不匹配。所以代码是没问题之前理解错了。 P11YAML与日志的整合 ​ 本节主要内容是YAML与日志文件的整合强烈建议学习本节之前花两分钟了解yaml的格式。如果需要直接运行代码就看第三节。 一、方法函数 ​ 在配置管理类Config中新增了两个成员函数LoadFromYaml、LookupBase分别用于从yml文件中载入配置内容和从配置内容中查找相应的目标项目。 LookupBase ​ 接收一个字符串参数在配置管理容器s_datas中查询目标配置。s_datas是ConfigVarMap类型它的定义也在下面。如果在容器中找到了目标则返回一个ConfigvarBase智能指针包含目标配置参数的名称和描述 ConfigvarBase::ptr Config::LookupBase(const std::string name) {auto it s_datas.find(name);return it s_datas.end() ? nullptr : it-second; }typedef std::mapstd::string, ConfigvarBase::ptr ConfigVarMap;LoadFromYaml ​ 代码解析我就直接放在注释中 void Config::LoadFromYaml(const YAML::Node root) {// 定义一个list装载的元素是string, node类型std::liststd::pairstd::string, const YAML::Node all_nodes;// root中可以获取到日志里面配置的内容ListAllMember则是把里面的内容分解成一个个节点细节后面会讲ListAllMember(, root, all_nodes);// 检验ListAllMember的遍历结果是否正确for(auto i : all_nodes) {std::string key i.first; if(key.empty()) continue;std::transform(key.begin(), key.end(), key.begin(), ::tolower);ConfigvarBase::ptr var LookupBase(key);// 如果找到if(var) {if(i.second.IsScalar()) {var-fromString(i.second.Scalar());} else {std::stringstream ss;ss i.second;var-fromString(ss.str());}}} }ListAllMember ​ 该函数包含3个参数 prefix前缀比如配置文件中的内容name:root解析时prefix namesylar在调用时传入的是一个空串为了便于理解我传入了一个null目的就是当遇到最外层的对象时比如log.yml中的logs:构造node时应该生成null : logs:node表示一个YAML类型节点如果当前的前缀合法就把prefixnode放入结果listoutput中output存储结果容器 整个解析流程比较简单 首先判断当前前缀是否合法如果前缀合法则创建一个pair存入output中如果当前的node是一个对象则继续遍历该对象里面的元素递归调用ListAllMember ListAllMember(null, root, all_nodes); // 调用应用时null记得还原为空串static void ListAllMember(const std::string prefix,const YAML::Node node,std::liststd::pairstd::string, const YAML::Node output) {// 判断prefix的合法性if(prefix.find_first_not_of(abcdefghijklmnopqrstuvwxyz._012345678) ! std::string::npos) {SYLAR_LOG_ERROR(SYLAR_LOG_ROOT()) Prefixe name invalid prefix : node;return;}output.push_back(std::make_pair(prefix, node));// 如果node是一个对象if(node.IsMap()) {for(auto it node.begin(); it ! node.end(); it) {// 遍历对象里面的元素ListAllMember(prefix.empty() ? it-first.Scalar() : prefix . it-first.Scalar(), it-second, output);}} }二、代码调试 ​ 写完代码后还是不太理解ListAllMember针对log.yml构建节点的方式然后通过gdb调试有了一定的收获不会调试的可以看看前面的文章我都写得非常详细这里就不列出调试的步骤直接用实际数据演示过程。 对于log.yml的数据省略了一些,logs是一个Map里面有两个数组system是一个对象也就是可以通过system.port获取相应元素的值 logs:- name: rootlevel: infoformatter: %d%T%m%nappenders:- type: FileLogAppenderfile: /root/Web-learning/sylar/root.txt- type: StdoutLogAppender- name: systemlevel: infoformatter: %d%T%m%nappenders:- type: FileLogAppenderfile: /root/Web-learning/sylar/system.txt- type: StdoutLogAppender system:port: 9900value: 15 载入上诉文件结果存储在all_nodes打印出来后结果如下 # 第一次打印i.first , i.second log.yml所有内容 logs:- name: rootlevel: infoformatter: %d%T%m%nappenders:- type: FileLogAppenderfile: /root/Web-learning/sylar/root.txt- type: StdoutLogAppender- name: systemlevel: infoformatter: %d%T%m%nappenders:- type: FileLogAppenderfile: /root/Web-learning/sylar/system.txt- type: StdoutLogAppender system:port: 9900value: 15 0 # 第二次打印i.first logs, i.second logs里面的元素 logs- name: rootlevel: infoformatter: %d%T%m%nappenders:- type: FileLogAppenderfile: /root/Web-learning/sylar/root.txt- type: StdoutLogAppender - name: systemlevel: infoformatter: %d%T%m%nappenders:- type: FileLogAppenderfile: /root/Web-learning/sylar/system.txt- type: StdoutLogAppender 1 # 第三次打印i.first system, i.second system里面的元素 systemport: 9900 value: 15 2 # 第三次打印i.first system, i.second system里面的元素 system.port9900 3 # 第四次打印i.first system.port, i.second 9900 system.value15 4 # 第四次打印i.first system.value, i.second 15# 对于每个i.first使用LookupBase查找打印结果 var.first: system.port var.second: 9900 var.first: system.value var.second: 15在LoadFromYaml中检验结果是否正确时回去all_nodes中查找只有在查到system.port和system.value才能成功 三、test_config结果 ​ 在运行之前需要更改CMakeLists.txt的内容我放在下面了 CMakeLists.txt cmake_minimum_required(VERSION 2.8) project(sylar)set(CMAKE_VERBOSE_MAKEFILE ON) set(CMAKE_CXX_FLAGS $ENV{CXXFLAGS} -rdynamic -O0 -g -stdc11 -Wall -Wno-deprecated -Werror -Wno-unused-function)include_directories(.) include_directories(/root/Web-learning/sylar/include) link_directories(/root/Web-learning/sylar/lib)find_library(YAMLCPP yaml-cpp) message(***, ${YAMLCPP})set(LIB_SRCsylar/log.ccsylar/util.ccsylar/config.cc)add_library(sylar SHARED ${LIB_SRC}) #add_library(sylar_static STATIC ${LIB_SRC}) #SET_TARGET_PROPERTIES(sylar_static PROPERTIES OUTPUT_NAME sylar)add_executable(test tests/test.cc) add_dependencies(test sylar) target_link_libraries(test sylar ${YAMLCPP})add_executable(test_config tests/test_config.cc) add_dependencies(test_config sylar) # target_link_libraries(test_config sylar -L/root/Web-learning/sylar/lib -lyaml-cpp) target_link_libraries(test_config sylar ${YAMLCPP})SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib) test_config #include iostream #include ../sylar/log.h #include ../sylar/util.h #include../sylar/config.h #includeyaml-cpp/yaml.hsylar::ConfigVarint::ptr g_int_value_config sylar::Config::Lookup(system.port, (int)8080, system port);sylar::ConfigVarfloat::ptr g_float_value_config sylar::Config::Lookup(system.value, (float)10.2f, system value);void print_yaml(const YAML::Node node, int level) {if(node.IsScalar()) {SYLAR_LOG_INFO(SYLAR_LOG_ROOT()) std::string(level * 4, ) node.Scalar() - node.Type() - level;} else if(node.IsNull()) {SYLAR_LOG_INFO(SYLAR_LOG_ROOT()) std::string(level * 4, ) NULL - node.Type() - level;} else if(node.IsMap()) {for(auto it node.begin(); it ! node.end(); it) {SYLAR_LOG_INFO(SYLAR_LOG_ROOT()) std::string(level * 4, ) it-first - it-second.Type() - level;print_yaml(it-second, level 1);}} else if(node.IsSequence()) {for(size_t i 0; i node.size(); i) {SYLAR_LOG_INFO(SYLAR_LOG_ROOT()) std::string(level * 4, ) i - node[i].Type() - level;print_yaml(node[i], level 1);}} }void test_yaml() {YAML::Node root YAML::LoadFile(/root/Web-learning/sylar/bin/conf/log.yml);print_yaml(root, 0); }void test_config() {SYLAR_LOG_INFO(SYLAR_LOG_ROOT()) before: g_int_value_config-getValue(); SYLAR_LOG_INFO(SYLAR_LOG_ROOT()) before: g_float_value_config-toString();YAML::Node root YAML::LoadFile(/root/Web-learning/sylar/bin/conf/log.yml);sylar::Config::LoadFromYaml(root);SYLAR_LOG_INFO(SYLAR_LOG_ROOT()) after: g_int_value_config-getValue(); SYLAR_LOG_INFO(SYLAR_LOG_ROOT()) after: g_float_value_config-toString(); }int main(int argc, char** argv) {// test_yaml();test_config();return 0; }结果 ​ 可以看到通过yml文件重新更改了配置参数的值。 四、小结 ​ 总的来说本节最关键的函数就是ListAllMember构建节点的过程可以把它的作用简单理解为想要构建诸如First xx.xx Second Val获取时就可以使用xx.xx val的形式。
http://www.pierceye.com/news/944933/

相关文章:

  • 河南建设厅网站查证报名网站开发多钱
  • 杭州做网站 做小程序网站百度知道怎么做推广
  • 网站防红链接怎么做国内设计欣赏网站
  • 网站被黑咋样的wordpress导入用户数据库
  • wordpress 插件设计搜索引擎优化常用方法
  • ps怎样做网站大图wordpress固定链接精简
  • 学校网站推广方案商城系统app
  • 图书馆管理系统产品介绍网站如何做seo
  • 威县企业做网站做网站游戏的网站有哪些
  • 如何做网站二维码广州营销型网站建设
  • 网站网页转小程序教程网站建设公司 枫子伽叩
  • 做民宿哪家网站最好网站推广技巧有哪些?
  • 北京做网站推广兼职wordpress 分段循环
  • 大气学校网站模板直播网站建设书籍
  • 榆林市住房和城市建设局网站网络系统管理比赛
  • 学校网站建设论文哪里网站备案最快
  • 上海公交建设公司官网seo排名优化工具
  • 网站设计与网站制作什么是网络营销中最容易出问题的步骤
  • 网站做自适应好不好网站开发结构图
  • wordpress sky主题东莞整站优化排名
  • 黑龙江 建设监理协会网站开发公司资质查询
  • 中标建设集团有限公司 网站怀化主要网站
  • 国外网站seo国外企业网站建设
  • 很简单的做设计的网站网站建设会议讲话
  • 泉港区建设局网站廉政配置wordpress环境
  • 公众号开发培训网站谷歌优化怎么做
  • 网站设计合理汕头市潮南区紧急提醒
  • 国外网站流量查询企业网站报价单
  • 聊城高唐网站建设公司wordpress设置域名
  • 有帮忙做儿童房设计的网站吗东莞横沥网站制作