分类 CPP 中的文章

关于 C++ 未定的行为

4 最后,不应该研究未定义行为( 对,第4点很重要!但是,cpp的未定义行为实在太多了,要提前学完也还真不容易。 给了const,又能const_cast。大家不应该经常cast,但是又没办法就是需要cast,比如派生类指针在继承树上候选类型之间的切换。开发者得一个个都经历,都思考,然后才能用好。 Bjarne Stroustrup说相信程序员都是聪明的,但是程序员很多时候并不相信自己足够聪明。我就经常在debug的时候怀疑人生。……

阅读全文

g++ -Wall 不会提示 narrow-cast 的警告

Preface 最近在使用 go 重构C++旧项目, 发现一个旧代码的bug,很有意思;下面展示一下简化的代码: 1 2 3 4 int64_t ip = 12345678; std::string str; str = ip; std::cout << "str = " << str << std::endl; // str = N 我的第一感觉是: 第三行应该编译报错吧,于是写了个hello world,然后g++ -Wall ..., 竟然编译过了还能正常运行, 神奇吧。 于是探其究竟,原来string重载了赋值符号=, 支持单个字符 char 的赋值,int64在这里发生了窄转换。 源码如下: 1 2 3 4 basic_string& operator=(_CharT __c) { this->assign(1, __c); return *this; } 这就解释了为啥输出字符"N", int64转换成 char,仅保留了最低的一个字节……

阅读全文

不建议使用std::thread

1 问题描述 使用std::thread 创建线程, 代码逻辑如果主动throw 某些异常, 但是用户又没有捕获。这时候程序会产生coredump, 但是分析coredump, 会发现调用栈是缺失的,根本无法定位具体问题。 为了方便理解,下面给一个例子: 1 2 3 4 5 6 7 8 9 10 11 12 13 // g++ -std=c++0x -g test.cpp -lpthread -o test #include <stdexcept> #include <thread> void foo() { throw std::runtime_error("foo"); } int main() { std::thread t(foo); t.join(); } 直接运行就会产生coredump, 通过gdb 分析: $ gdb test core.1243 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Program received signal SIGABRT, Aborted. [Switching to Thread 0x7ffff7fd0700 (LWP 10278)] 0x000000318f036285 in raise () from /lib64/libc.so.6 Missing separate debuginfos, use: debuginfo-install glibc-2.14.90-24.fc16.9.x86_64 libgcc-4.6.3-2.fc16.x86_64 libstdc++-4.6.3-2.fc16.x86_64 (gdb) bt #0 0x000000318f036285 in raise () from /lib64/libc.so.6 #1 0x000000318f037b9b in abort () from /lib64/libc.so.6 #2 0x00000031964bbc5d in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib64/libstdc++.so.6 #3 0x00000031964b9e16 in……

阅读全文

C++14 lambda 用法

1 嵌套lambda表达式 写一个lambda表达式A,其入参是一个lambda表达式B: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #include <cstdio> #include <iostream> namespace example01 { template<typename Func> void run_task(Func &&func) { int arg = 100; printf("1. arg >> %d\n", arg); /** * 定义一个别名,进行引用捕获 * (注意:引用捕获时,请考虑被捕获对象的生命周期) */ func([&i = arg]() mutable { ++i; printf("3. i == %d\n", i); throw std::logic_error("逻辑错误"); }); printf("6. arg << %d\n", arg); } inline void run() { //写一个lambda表达式A,其入参是一个lambda表达式B example01::run_task([](auto get_ex) { printf("2. start check\n"); try { get_ex(); } catch (std::exception &ex) { std::cout << "4.……

阅读全文

使用 CMake 快速制作 RPM 安装包

1 Preface 最近对框架进行了改造,支持yaml格式的配置文件, 使用到了 yaml-cpp 这个第三方库, yum官方提供的是 0.5.1 版本(依赖boost),看到最新版 0.6.3 已经去除了boost的依赖, 于时想自己做一个包。 制作 rpm 包通用的方式是: 直接使用rpm-build, 编写project.spec,这样就需要了解spec的语法规则。 今天不经意在网上搜到,可以用CMake来制作RPM包(因为我们的 C++ 项目也是采用 CMake 进行编译的)。 CMake打包的基本原理是:CMake内部有一个cpack工具,支持调用不同的打包工具(比如 rpmbuild) 下面我们就基于C……

阅读全文

Multithreading-with-ZeroMQ

本文翻译自ZeroMQ文档的一小部分内容, 该段落提供了解决多线程问题的一个绝佳方式。 这是前辈30多年的并发编程经验之谈! 点击阅读原文:Multithreading-with-ZeroMQ Preface ZeroMQ(又称为ØMQ,0MQ,或zmq)看起来像一个可嵌入的网络编程库, 但用起来更像是一个并发框架。 它为你提供的套接字(sockets), 能以进程间, 进程内, TCP 和多播等多种方式传输原子消息。 你可以用fan-out, pub-sub, 任务分发, 和 req-rep 等多种模式, 给套接字建立多对多的连接。 它速度之快足以构建集群产品。 它的异步I……

阅读全文

C++ RAII

什么是RAII ? RAII即“Resource Acquisition Is Initialization”,也称为“资源获取即初始化”。是C++语言的一种管理资源、避免泄漏的惯用法。利用的就是C++构造的对象最终会被销毁的原则。 RAII的做法是使用一个对象,在其构造时获取对应的资源,在对象生命期内控制对资源的访问,使之始终保持有效,最后在对象析构的时候,释放构造时获取的资源。……

阅读全文

c和c++混用技巧

1 用C-style 来访问vector 1 2 3 4 5 6 7 8 vector<char*> str; str.push_back("abc"); str.push_back("123"); //按照 C-style 来访问vector char** ptr= str.data(); for(int i =0;i<2;++i) printf("%s\n",ptr[i]);……

阅读全文

C++11 std::function 和 std::bind

1 std::bind std::bind 可以用来绑定一个函数 std::placeholders; 定义有_1、_2、_3 … 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include <functional> using namespace std; using namespace std::placeholders; int f(int, char, double); int main() { // 翻转参数顺序 auto frev = bind(f, _3, _2, _1); int x = frev(1.2, 'w', 7); cout<<x<<endl; return 0; } int f(int a, char b , double c) { cout<<"a=="<< a <<",b==" <<b << ",c=="<<c <<endl; return 0; } 2 std::function std::function 可以用来定义一个函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 int add(int a, int b){ return a+b; } auto mod=[](int a, int b){return a%b;}; struct divide{ int operator()(int m, int n){ return m/n; } }; int main() { function<int(int,int)> func1= add; function<int(int,int)> func2= mod; function<int(int,int)> func3= divide(); cout<<func1(5, 6)<<endl; cout<<func2(5, 6)<<endl; cout<<func3(5, 6)<<endl; return 0; }……

阅读全文

最近文章

分类

友情链接

标签

其它