Compiling Error: error C2664: 'void TestFun01(std::string &)': cannot convert argument 1 from 'const char [5]' to 'std::string &' Solution: add const to std::string& which is a parameter of function, like this: void TestFun01(const std::string& text) { std::cout << text; } void TestFun02() { TestFun01("abcd"); } this would produce compiling error: void TestFun01(std::string& text) { std::cout << text; } void TestFun02() { TestFun01("abcd"); }

Continue reading

shared_ptr 语法: #include <memory> shared_ptr<A> x(new A); shared_ptr 相当于 对象引用计数器。每当对 shared_ptr 赋值操作一次,则其引用对象的计数+1。当某对象的引用计数为0时,则该对象自动销毁。 weak_ptr 语法: #include <memory> weak_ptr<A> x(new A); weak_ptr 典型应用是缓存:例如我们在缓存中存放了一个 raw pointer 来指向某个对象,如果这个对象在其他地方被销毁了,那么缓存中的这个 raw pointer 指向的对象不存在。如果我们希望某个对象在其他地方被销毁时,缓存中指向该对象的指针也马上被置为 null,那么就可以使用 weak_ptr。 参考自: shared_ptr and weak_ptr differences https://stackoverflow.com/questions/4984381/shared-ptr-and-weak-ptr-differences When is std::weak_ptr useful? https://stackoverflow.com/questions/12030650/when-is-stdweak-ptr-useful

Continue reading

keywords:C++ 非静态成员函数作为回调函数并实现继承多态 Base.hpp #pragma once class Base { public: virtual void TestFun1(int Param) {} virtual void TestFun2(int Param) {} }; Child.hpp #pragma once #include <iostream> #include "Base.hpp" class Child : public Base { public: void TestFun1(int Param) override { printf("Fun1 : %d\n", Param); } void TestFun2(int Param) override { printf("Fun2 : %d\n", Param); } }; EventManager.h // Fill out your copyright notice in the Description page of Project Settings.

Continue reading

keywords:C++ 用索引删除 std::vector 中的数组元素 To delete a single element, you could do: std::vector<int> vec; vec.push_back(6); vec.push_back(-17); vec.push_back(12); // Deletes the second element (vec[1]) vec.erase(vec.begin() + 1); Or, to delete more than one element at once: // Deletes the second through third elements (vec[1], vec[2]) vec.erase(vec.begin() + 1, vec.begin() + 3); 参考自:How do I erase an element from std::vector<> by index? https://stackoverflow.com/questions/875103/how-do-i-erase-an-element-from-stdvector-by-index 无论精神多么独立的人,感情却总是在寻找一种依附,寻找一种归宿。---路遥《平凡的世界》

Continue reading

keywords:匿名类,匿名结构体、构造函数、析构函数、Lambda 为匿名类添加构造函数与析构函数,有两种方式: C++98中在匿名类内部加一个命名类 C++11 Lambda语法 C++98 C++98中,可以在匿名类内部放一个命名类(named class ),然后再为命名类添加构造和析构函数,当匿名类构造或析构时,就会去调用命名类的构造函数和析构函数。 #include <iostream> #include <cmath> int main() { struct { struct S { double a; int b; S() : a(sqrt(4)), b(42) { std::cout << "constructed" << std::endl; } ~S() { std::cout << "destructed" << std::endl; } } s; } instance1, instance2; std::cout << "body" << std::endl; } C++11 Lambda #include <iostream> #include <cmath> int main() { struct { double a { sqrt(4) }; int b { []{ std::cout << "constructed" << std::endl; return 42; }() }; } instance1, instance2; } 参考 How to add constructors/destructors to an unnamed class?

Continue reading

原文:http://www.cnblogs.com/graphics/archive/2010/07/05/1771110.html #include <iostream> #include <map> #include <string> using namespace std ; int main(void) { map<int, string> m ; m.insert(pair<int, string>(1, "abc")) ; m.insert(pair<int, string>(2, "def")) ; m.insert(pair<int, string>(3, "def")) ; m.insert(pair<int, string>(4, "ghi")) ; map<int, string>::iterator itor ; // 错误的写法 for (itor = m.begin(); itor != m.end(); ++itor) { if (itor->second == "def") { m.erase(itor) ; // map是关联式容器,调用erase后,当前迭代器已经失效 } } // 正确的写法 for (itor = m.begin(); itor != m.end();) { if (itor->second == "def") { m.

Continue reading

ifstream,ofstream读写二进制文件 #include <iostream> #include <fstream> using namespace std; int main(int argc, char** argv) { int a[5] = {1,2,3,4,5}; int b[5]; ofstream ouF; ouF.open("./me.dat", std::ofstream::binary); ouF.write(reinterpret_cast<const char*>(a), sizeof(int)*5); ouF.close(); ifstream inF; inF.open("./me.dat", std::ifstream::binary); inF.read(reinterpret_cast<char*>(b), sizeof(int)*5); inF.close(); for (int i = 0; i < 5; i++) { cout << b[i] << endl; } return 0; } 参考自:https://blog.csdn.net/bendanban/article/details/30039193 C模式读写二进制文件 //采用C模式写二进制文件 void DataWrite_CMode() { //准备数据 double pos[200]; for(int i = 0; i < 200; i ++ ) pos[i] = i ; //写出数据 FILE *fid; fid = fopen("binary.

Continue reading

一种获取bool值的技巧,在获取bool值的同时有保证代码有可读性。 比如这种写法,直接将一个指针赋给一个bool值,看上去有点怪,不利于阅读。 void Test(A* Ptr) { bool b = Ptr; ... } 但是加两个感叹号,就可以清楚表明我是要明确获得一个bool。 void Test(A* Ptr) { bool b = !!Ptr; ... } 当然用三元运算符? : 也可以,不过要多敲一些字符。 void Test(A* Ptr) { bool b = Ptr ? true : false; ... } 三种方式的CPU指令数是完全一样,开销相同。 bool b = !!Ptr; 003EA318 cmp dword ptr [Ptr],0 003EA31C je Test+6Ah (03EA32Ah) 003EA31E mov dword ptr [ebp-0E8h],1 003EA328 jmp Test+74h (03EA334h) 003EA32A mov dword ptr [ebp-0E8h],0 003EA334 mov al,byte ptr [ebp-0E8h] 003EA33A mov byte ptr [b],al 时间是一只藏在黑暗中的温柔的手,在你一出神一恍惚之间,物走星移。----龙应台《目送》

Continue reading

keywords:alias template、模板别名、模板的模板 如果模版的type(T)不是具体类型,也是一个模板,C++11之前的语法不支持,现在C++11提供了新的语法支持这种场景:using identifier attr(optional) = type-id 示例: template <template <typename> class> struct X { X() { std::cout << "1"; } }; template <typename> struct Y { }; template <typename T> using Z = Y<T>; template <> struct X<Y> { X() { std::cout << "2"; } }; int main(int argc, char* argv[]) { X<Y> x1; X<Z> x2; } 运行结果: 21 Type alias, alias template (since C++11) http://en.cppreference.com/w/cpp/language/type_alias 尺之木必有节目,寸之玉必有瑕瓋。---《吕氏春秋》

Continue reading

最近两年一直是在UE4的编译器下使用C++,标准C++的一些基础都快忘了。。。 示例代码: #include <iostream> class CA { public: //两种初始化成员变量的方法 CA() : ia_(11) { fa_ = 0.f; } CA(int val) : ia_(val) { fa_ = 0.f; } //要想让子类能够访问,修饰符不可为private protected: int ia_; private: float fa_; }; class CB : public CA { public: //显示调用父类的有参构造函数 CB() : CA(33), ib_(22) { } int ib() { return ib_; } int ia() { return ia_; } private: int ib_; }; int main(int argc, char* argv[]) { CB b; std::cout << b.

Continue reading

参考自:https://stackoverflow.com/questions/2124339/c-preprocessor-va-args-number-of-arguments #include <stdio.h> #include <string.h> #include <stdarg.h> #define NUMARGS(...) (sizeof((int[]){__VA_ARGS__})/sizeof(int)) #define SUM(...) (sum(NUMARGS(__VA_ARGS__), __VA_ARGS__)) void sum(int numargs, ...); int main(int argc, char *argv[]) { SUM(1); SUM(1, 2); SUM(1, 2, 3); SUM(1, 2, 3, 4); return 1; } void sum(int numargs, ...) { int total = 0; va_list ap; printf("sum() called with %d params:", numargs); va_start(ap, numargs); while (numargs--) total += va_arg(ap, int); va_end(ap); printf(" %d\n", total); return; } 晚食以当肉,安步以当车,无罪以当贵,清静贞正以当虞。---《战国策》

Continue reading

printf函数源码实现 #include <stdio.h> #include <stdarg.h> //va_start(arg,format),初始化参数指针arg,将函数参数format右边第一个参数地址赋值给arg //format必须是一个参数的指针,所以,此种类型函数至少要有一个普通的参数, //从而提供给va_start ,这样va_start才能找到可变参数在栈上的位置。 //va_arg(arg,char),获得arg指向参数的值,同时使arg指向下一个参数,char用来指名当前参数型 //va_end 在有些实现中可能会把arg改成无效值,这里,是把arg指针指向了 NULL,避免出现野指针 void print(const char *format, ...) { va_list arg; va_start(arg, format); while (*format) { char ret = *format; if (ret == '%') { switch (*++format) { case 'c': { char ch = va_arg(arg, char); putchar(ch); break; } case 's': { char *pc = va_arg(arg, char *); while (*pc) { putchar(*pc); pc++; } break; } default: break; } } else { putchar(*format); } format++; } va_end(arg); } int main() { print("%s %s %c%c%c%c%c!

Continue reading

比如要设置一连串的回调函数来响应键盘的0到9数字键,注册回调函数时无法把数字0到9作为函数参数一起注册,那么有没其他办法?答案肯定是有!具体方式如下: 1,先定义好需要回调的函数,假如: void TestCallback(int index); 2,再定义一个模板函数将上面的函数封装: template<int index> void TestCallback() { TestCallback(index); } 3,最后在注册回调时,将数字作为模板类型来注册: CallbackMaster->Bind(&MyClass::TestCallback<9>); 不积跬步,无以至千里;不积小流,无以成江海。骐骥一跃,不能十步;驽马十驾,功在不舍。锲而舍之,朽木不折;锲而不舍,金石可镂。——《荀子》

Continue reading

之前网上一直有这么一条for循环优化建议: 将size提到第一个分号前,这样可以提高循环的效率,例如: std::vector<int> aaa; for (size_t i = 0, size = aaa.size(); i < size; i++) { printf("bbb"); } 这个如果是很多年前,应该是有道理的,但是现在的编译器足够聪明,很多看起不够优化的代码,编译器会帮你处理。 以下是在VS2015下的汇编代码,结果是:size不前提反而可以节省两次mov指令。 size放在第一个分号后: for (size_t i = 0; i < aaa.size(); i++) 00007FF7629E3147 mov qword ptr [rbp+48h],0 00007FF7629E314F jmp _20161011+3Ch (07FF7629E315Ch) 00007FF7629E3151 mov rax,qword ptr [rbp+48h] 00007FF7629E3155 inc rax 00007FF7629E3158 mov qword ptr [rbp+48h],rax 00007FF7629E315C lea rcx,[aaa] 00007FF7629E3160 call std::vector<int,std::allocator<int> >::size (07FF7629E16BDh) 00007FF7629E3165 cmp qword ptr [rbp+48h],rax 00007FF7629E3169 jae _20161011+59h (07FF7629E3179h) size提到第一个分号前:

Continue reading

原文:http://ju.outofmemory.cn/entry/149128 struct A { int x:1; int y:2; int z:31; }; 此时是正确的 但是: struct A { int x:1; int y:2; int z:33; }; 此时就会有编译错误:error C2034: 'z' : type of bit field too small for number of bits 原文:http://zhidao.baidu.com/question/60696610.html struct/class定义中在成员后面加冒号“:1”是什么意思? 这是位域操作的表示方法,也就是说后面加上“:1”的意思是这个成员的大小占所定义类型的1 bit,“:2”占2 bit,依次类推。当然大小不能超过所定义类型包含的总bit数。 一个bytes(字节)是8 bit(bit)。例如你的结构中定义的类型是u_char,一个字节,共8bit,最大就不能超过8。 32位机下, short是2字节,共16bit,最大就不能超过16. int是4字节,共32bit,最大就不能超过32. 依次类推。 这样定义比较省空间。例如你上面的结构,定义的变量类型是u_char,是一字节类型,即8bit。 fc_subtype占了4bit,fc_type占2bit,fc_protocol_version占2bit,共8bit,正好是一个字节。 其他八个成员,各占1bit,共8bit,正好也是一个字节。 因此你的结构的大小如果用sizeof(struct frame_control)计算,就是2bytes.

Continue reading

Author's picture

Neil Wang

久长唯有品格

To Be Marvelous

Yichang·Hubei