09 2024 档案
摘要:在4.11.3节(第145页)中我们说过,const_cast 在重载函数的情景中最有用。举个例子,回忆6.3.2节(第201页)的shorterstring 函数: //比较两个string对象的长度,返回较短的那个引用 const string &shorterString(const stri
阅读全文
摘要:▲ 《C++ Primer》 P302 assign list<string> names; vector<const char *> old_c_str{ "娃哈哈", "孟菲斯", "Hello Wold!" }; names.assign(old_c_str.cbegin(), old_c_s
阅读全文
摘要:▲ 顺序容器类型 《C++ Primer》 P294
阅读全文
摘要:IO 库: istream(输入流)类型,提供输入操作。 ostream(输出流)类型,提供输出操作。 cin,一个istream对象,从标准输入读取数据。 cout,一个ostream对象,向标准输出写入数据。 cerr,一个ostream对象,通常用于输出程序错误消息,写入到标准错误。 >>运算
阅读全文
摘要:这样转化是没有问题的。 int a{ 100 }; const void *p = &a; const int *pi = static_cast<const int *>(p); cout << *pi << endl; 输出: 100 void * 转换貌似原来什么类型,再强转回去没啥问题,动态
阅读全文
摘要:花括号的形式{},进行列表初始化,在C++11中初始化变量到了全面的应用。 可参看《C++ Primer》 P39 P76 P88 等相关内容信息。 Note: 当我们提供一个类内初始值时,必须以符号=或者花括号表示。《C++ Primer》 P246。 如下: class Dog { public
阅读全文
摘要:#include <iostream> #include <string> #include <memory> #include <vector> #include <thread> #include <queue> #include <functional> #include <mutex> us
阅读全文
摘要:async 和 future 这个和 C# 的 Task 有点像。 #include <iostream> #include <string> #include <memory> #include <future> #include <thread> using namespace std; int
阅读全文
摘要:#if 1 #include <iostream> #include <memory> #include <mutex> using namespace std; class Singleton { public: static Singleton &getInstance() { std::cal
阅读全文
摘要:int main() { constexpr size_t rowCnt = 3, colCnt = 4; int ia[rowCnt][colCnt]; // 使用 for 循环遍历初始赋值 for (size_t i = 0; i != rowCnt; ++i) { for (size_t j
阅读全文
摘要:▲《C++ Primer》 P109 我们无法保证 c_str 函数返回的数组一直有效,事实上,如果后续的操作改变了 string 的值就可能让之前返回的数组失去效用。 WARNING: 如果执行完 c_str() 函数后程序想一直都能使用其返回的数组,最好将该数组重新拷贝一份。
阅读全文
摘要:▲ 《C++ Primer》 P96 指针也都支持上面的操作。 两个指针相减的结果的类型是一种名为 ptrdiff_t的标准库类型,和 size_t 一样,ptrdiff_t 也是一种定义在 cstddef 头文件中的机器相关的类型。因为差值可能为负值,所以 ptrdiff_t 是一种带符号类型。(
阅读全文
摘要:当使用数组作为一个 auto(参见 2.5.2节,第61页)变量的初始值时,推断得到的类型是指针而非数组: int ia[]= {0,1,2,3,4,5,6,7,8,9}; // ia是一个含有10 个整数的数组 auto ia2(ia); // ia2 是一个整型指针,指向 ia 的第一个元素 i
阅读全文
摘要:显式初始化数组元素 如果指明了维度,那么初始值的总数量不应该超出指定的大小。如果维度比提供的初始值数量大,则用提供的初始值初始化靠前的元素,剩下的元素被初始化成默认值(参见 3.3.1节,第 88 页): const unsigned s=3; int ial[sz]={0,1,2}; //含有3个
阅读全文
摘要:▲ 《C++ Primer》 P30 ▲ 《C++ Primer》 P38
阅读全文
摘要:▲ 《C++ Primer》 P96 ▲《C++ Primer》 P99 迭代器距离类型:difference_type,string和vector都定义了difference_type,因为这个距离可正可负,所以difference type是带符号类型的。
阅读全文
摘要:可参考 《C++ Primer》 P197 页
阅读全文
摘要:▲ 《C++ Primer》 P87 ▲ 《C++ Primer》 P91
阅读全文
摘要:如果循环体内部包含有向vector对象添加元素的语句,则不能使用范围for循环,具体原因将在5.4.3节(第168页)详细解释。 WARNING:范围for语句体内不应改变其所遍历序列的大小。 ▲《C++ Primer》 P91 不能在范围 for 循环中向 vector 对象添加元素。另外一个限制
阅读全文
摘要:vector<int> vl(10); //v1有10 个元素,每个的值都是0 vector<int> v2{10}; //v2有1个元素,该元素的值是 10 vector<int> v3(10,1); //v3有10个元素,每个的值都是1 vector<int> v4{10,1}; //v4有2个
阅读全文
摘要:const string hexdigits = "0123456789ABCDEF";//可能的十六进制数字 《C++ Primer》 P85
阅读全文
摘要:《C++ Primer》 P82
阅读全文
摘要:因为某些历史原因,也为了与℃兼容,所以 C++ 语言中的字符串字面值并不是标准库类型 string 的对象。切记,字符串字面值与string是不同的类型。 所以,不能将两个字面值字符串直接相加+。 参考:《C++ Primer》 P81
阅读全文
摘要:class Dog { public: void Update_Func(short i); short (Dog::*pfunc)(short); std::function<short(short)> ffunc; public: short goodMorning(short id); sho
阅读全文
摘要:一般而言,一个左值表达式表示的是一个对象的身份,而一个右值表达式表示的是对象的值。 我们不能将其绑定到要求转换的表达式、字面常量或是返回右值的表达式(参见 2.3.1节,第 46页)。右值引用有着完全相反的绑定特性:我们可以将一个右值引用绑定到这类表达式上,但不能将一个右值引用直接绑定到一个左值上:
阅读全文
摘要:希望从表达式的类型推断出要定义的变量的类型,但是不想用该表达式的值初始化变量。 decltype(f())sum =x; //sum的类型就是函数f的返回类型 编译器并不实际调用函数f,而是使用当调用发生时f的返回值类型作为sum 的类型。 decltype 处理顶层 const 和引用的方式与 a
阅读全文
摘要:int i=0, &r = i; auto a=r; // (int a) a是一个整数(r是i的别名,而i是一个整数) auto 一般会忽略掉顶层 const(参见 2.4.3节,第57页),同时底层 const 则会保留下来,比如当初始值是一个指向常量的指针时: const int ci=i,
阅读全文
摘要:“工具”->“选项”->“文本编辑器”->“C/C++”->“代码样式”->“格式设置”->“间距”->“指针/引用对齐方式”->“右对齐”。
阅读全文
摘要:指针、常量和类型别名 如果某个类型别名指代的是复合类型或常量,那么把它用到声明语句里就会产生意想不到的后果。例如下面的声明语句用到了类型pstring,它实际上是类型 char* 的别名 typedef char *pstring; const pstring cstr=0; //cstr是指向ch
阅读全文
摘要:定义静态成员 和其他的成员函数一样,我们既可以在类的内部也可以在类的外部定义静态成员函数。当在类的外部定义静态成员时,不能重复static关键字,该关键字只出现在类内部的声明语句: void Account::rate(double newRate) { interestRate = newRate
阅读全文
摘要:拷贝构造函数 拷贝构造函数的第一个参数必须是一个引用类型。虽然我们可以定义一个接受非 const 引用的拷贝构造函数,但此参数几乎总是一个 const 的引用。 拷贝构造函数在几种情况下都会被隐式地使用。因此,拷贝构造函数通常不应该是explicit的(参见 7.5.4节,第 265 页)。 一般情
阅读全文
摘要:常量表达式(const expression)是指值不会改变并且在编译过程就能得到计算结果的表达式。 指针和 constexpr 必须明确一点,在 constexpr 声明中如果定义了一个指针,限定符constexpr 仅对指针有效,与指针所指的对象无关: const int *p=nullptr;
阅读全文
摘要:struct Base { double x{ 111.1 }; }; struct Derive :public Base { double y{ 222.2 }; Derive& operator=(const Derive& obj) { if (&obj == this) { return
阅读全文
摘要:int i =0; int *const pl = &i; //不能改变p1的值,这是一个顶层 const const int ci=42; //不能改变 ci的值,这是一个顶层 const const int *p2 =&ci; //允许改变p2的值,这是一个底层 const const int
阅读全文
摘要:下面这种情况显然我们是了解的: const int ci=1024; const int &rl=ci; //正确:引用及其对应的对象都是常量 r1 =42; //错误:r1是对常量的引用 int &r2=ci; //错误:试图让一个非常量引用指向一个常量对象 初始化和对 const 的引用 2.3
阅读全文
摘要:如果类派生自 C++ 标准库中的类型,而你正在编译调试版本 (/MTd),并且编译器错误消息引用 _Container_base,则可以忽略 C4251。 应慎重将 __declspec(dllexport) 或 __declspec(dllimport) 添加到类中,因为这大概率会成为一种不正确的
阅读全文
摘要:/*****class Base*****/ class Base { public: Base(); virtual ~Base(); protected: struct Impl; Impl* m_Impl; }; struct Base::Impl { int num{ 100 }; }; B
阅读全文
摘要:默认状态下,const 对象仅在文件内有效。 const int bufSize=512;//输入缓冲区大小 编译器将在编译过程中把用到该变量的地方都替换成对应的值。也就是说,编译器会找到代码中所有用到 bufsize 的地方,然后用 512 替换。 某些时候有这样一种 const 变量,它的初始值
阅读全文
摘要:声明 int *ipl,*ip2; // ipl和 ip2 都是指向 int 型对象的指针 double dp,*dp2; // dp2是指向 double型对象的指针,dp是double 型对象 因为引用不是对象,没有实际地址,所以不能定义指向引用的指针。 指针值 指针的值(即地址)应属下列4种状
阅读全文
摘要:int a{ 10 }; { cout << a << endl; int b{ 20 }; } //cout << b << endl; // 不可访问,只能从内往外查找名字。 作用域是从内往外查找的。 作用域中一旦声明了某个名字,它所嵌套着的所有作用域中都能访问该名字。同时,允许在内层作用域中重
阅读全文
摘要:变量声明规定了变量的类型和名字,在这一点上定义与之相同。但是除此之外,定义还申请存储空间,也可能会为变量赋一个初始值。 如果想声明一个变量而非定义它,就在变量名前添加关键字 extern,而且不要显式地初始化变量: extern int i; // 声明i而非定义i int j; // 声明并定义了
阅读全文
摘要:列表初始化 当用于内置类型的变量时,这种初始化形式有一个重要特点:如果我们使用列表初始化且初始值存在丢失信息的风险,则编译器将报错: long double ld=3.1415926536; int a{ld},b={ld}; //错误:转换未执行,因为存在丢失信息的危险 int c(ld),d=
阅读全文
摘要:class Base { public: virtual ~Base() { cout << "~Base" << '\n'; } }; class Derived : public Base { public: ~Derived() { cout << "~Derived" << '\n'; }
阅读全文
摘要:一 有符号整数和无符号整数相加时,把负数转换成无符号数类似于直接给无符号数赋一个负值,结果等于这个负数加上无符号数的模。 unsigned int n = 300; int m = -500; cout << m + m << '\n'; cout << n + m << '\n'; 输出: -10
阅读全文
摘要:#include <iostream> #include <type_traits> using namespace std; namespace { class IAnimal { public: virtual void say() = 0; }; class Dog : IAnimal { p
阅读全文
摘要:如果我们未定义拷贝控制成员,编译器会为我们合成;如一个类未定义构造函数,编译器会为我们合成一个默认的构造函数。 合成拷贝控制成员可能是删除的情况: 如果类中有成员的析构函数是删除的或不可访问的(private): a. 则类的合成析构函数被定义为删除的; b. 则合成拷贝构造函数被定义为删除的; c
阅读全文
摘要:#include <map> #include <vector> #include <iostream> #include <string> void FitCenterByLeastSquares(std::map<int, std::vector<double>> mapPoint, std::
阅读全文
摘要:#define _CRT_SECURE_NO_WARNINGS /*多字节转宽字节*/ int unsafe_mbstowcs() { // 设置当前的 locale 为用户环境变量指定的 locale setlocale(LC_ALL, ""); // 定义多字节字符串 const char* m
阅读全文