C++语言
文章平均质量分 54
主要介绍语言特性
asdfghwunai
这个作者很懒,什么都没留下…
展开
-
C++ 高级主题杂记(较冷门)
1、指针类型的转换,失败会返回0:2、引用类型的转换,失败只会抛异常:1、返回值类型是type_info或type_info的派生类。2、对数组或函数,结果是数组类型;对非类类型和不含虚函数的类,结果是静态类型;对含有虚函数的类,求值是动态类型(运行时获取)3、注意不要把对象写成了指针,正确的:错误的:1、主要讲具有继承关系的类如何实现相等运算符。1、通过typeid获取typeinfo原创 2024-02-28 14:26:41 · 174 阅读 · 0 评论 -
拷贝、赋值和析构函数(稍微进阶)
拷贝构造函数基本形式注意形参类型是类类型,不能声明为explicit,因为有些地方需要隐式转换class Foo{public: Foo(); Foo(const Foo&);};合成拷贝构造函数你不声明构造函数,也会给你一个合成的。浅拷贝问题。调用时机1.非引用类型形参2.返回非引用类型3.使用{}初始化一个数组4.标准库容...原创 2019-04-19 12:23:55 · 199 阅读 · 0 评论 -
基类和派生类
基类定义class Quote{public: Quote() = default; Quote(const std::string &book, double sales_price): bookNo(book), price(sales_price){ } std::string isbn(){ return bookNo;...原创 2019-04-26 22:01:26 · 253 阅读 · 0 评论 -
友元(非重点)
友元初步(7.2.1节)作用友元打破封装,注意友元不是成员,无视private的控制,更无视其他访问级别了。声明方法类里面加friend声明一次(仅代表声明访问权限,不是真正的声明),类外还要再声明一次。友元再探(7.3.4节)把其他非成员函数作为友元略把其他类作为友元友元类完全可以访问Screen类的所有成员。class Screen{ fri...原创 2019-04-03 12:30:19 · 68 阅读 · 0 评论 -
构造、拷贝、赋值、析构(初级)
构造基本内容不能声明为const原因是常量对象完成构造函数的初始化后才获得常量属性,在此期间构造函数可以操作常量对象,声明也没用。合成的默认构造函数假如我们没有显式定义任何构造函数,编译器将为我们合成一个默认构造函数来初始化我们的成员变量。初始化原则:1.有类内初始值的,按这些值初始化。2.没有的,按变量默认初始化方式(未定义的行为)。class A{ ...原创 2019-04-02 19:24:22 · 106 阅读 · 0 评论 -
const成员函数
this指针成员函数有个隐含的参数this指针,this是一个指向对象的常量指针。比如类型为Sales_data的对象的this指针形如Sales_data * const this;而在成员函数后加上const限定符后,this指针的含义发生了变化const Sales_data * const this;限制调用const成员函数只能被const对象,其他const...原创 2019-04-02 16:27:19 · 88 阅读 · 0 评论 -
左值和右值
意义运算符需要左值或右值来作为操作对象。判断左值和右值:当一个对象被用作右值时,需要的是其值(内容);被用作左值时,需要的是其内存位置。左值能被当做右值用,用的是左值的内容;而右值当不成左值。...原创 2019-03-28 19:36:58 · 97 阅读 · 0 评论 -
指针和数组
一维数组1.数组名等价于一个常量指针,指向数组的第一个元素。string nums[] = {"one","two","three"};string *p = nums;string *p2 = &nums[0];2. 使用begin()和end()函数取得相应的指针int ia[]= {0,1,2,3}; int *beg = begin(ia);int...原创 2019-03-28 19:23:50 · 64 阅读 · 0 评论 -
内置数组
基本大小初始化只能用常量表达式初始化,否则报错。unsigned int cnt = 42;int arr1[cnt]; //primer说 xxx,但是好像编译没问题 int arr2[10]; constexpr unsigned sz = 42;int *parr[sz]; int arr3[get_size()]; //返回值为cons...原创 2019-03-28 13:37:09 · 671 阅读 · 0 评论 -
迭代器:支持string和容器的元素访问
迭代器类型分为两种:iterator和const_iterator,其中iterator只能操作非const对象。vector<int>::iterator it1;string::iterator it2; vector<int>::const_iterator it3;string::const_iterator it4;迭代器失效这是一...原创 2019-03-28 13:10:39 · 199 阅读 · 0 评论 -
基类和子类的类型转换
绑定例外一般指针和引用和要绑定的对象属于同种类型,但基类指针或引用的绑定是一个例外。静态类型和动态类型静态类型编译时就确定,动态类型是运行时查对象内存才知道。静态类型是Quote&,动态类型是运行时调用函数才知道。一致情况如果形参不是引用或指针,那么静态类型和动态类型一致类型转换基类向派生类直接转是不行的Quote base;Bulk_quote...原创 2019-04-26 22:45:47 · 1041 阅读 · 0 评论 -
右值引用&&
动机对象之间的拷贝太费时,即将销毁的对象不必拷贝,仅仅移动就行。右值引用回忆左值是要用表达式的地址,右值是要表达式的值。左值引用是&,右值引用是&&。左值不能指右值,右值不能指左值。int i = 42;int &r = i;int &&rr = i; //xxx,右值不能指左值。int &r2 = i*2; /...原创 2019-04-22 21:42:06 · 390 阅读 · 0 评论 -
虚析构函数
动机防止少删除派生类对象写法调用虚析构造成不合成移动操作管它合不合成,反正我又不敢用合成的原创 2019-04-27 22:26:38 · 341 阅读 · 0 评论 -
继承中的类作用域
引出Bulk_quote bulk;cout <<bulk.isbn()<<endl;静态类型决定由谁开始向上搜索Quote是Disc_quote的父亲,Disc_quote是Bulk_quote的父亲。在Disc_quote中加入以下函数。给出以下示例:bulkP从孙子代开始搜索,itemP从基类开始搜索。再次澄清名字查找规则...原创 2019-04-27 22:16:45 · 172 阅读 · 0 评论 -
继承中的访问控制
proteced例外派生类通过派生类对象访问受保护成员,不能通过基类对象访问受保护成员。三种继承方式public继承维持基类关键字不变。protected继承把基类里的pubulic设为protected。降级private继承把基类里的public和protected变为private。降级。派生类向基类转换的可访问性class A{}; class...原创 2019-04-27 21:40:14 · 501 阅读 · 0 评论 -
抽象基类
动机有时基类对象是完全没有意义的,比如动物类,或者DIsc_quote类,里面的net_price函数没有意义。这时可以在类里面包含纯虚函数来禁止创建对象。纯虚函数DIsc_quote类是一个通用概念,里面的net_price函数无意义,并且创建该对象也没意义。进化成抽象基类含有纯虚函数就不能见对象了。Disc_quote dis; //xxx,含有纯虚函数Bul...原创 2019-04-27 17:01:56 · 156 阅读 · 0 评论 -
虚函数
定不定义普通成员函数只要没用到可以不写定义,但虚函数只要在主函数被用到,所有父类和子类必须都定义该函数,因为编译器只有在运行时才能确定用到哪个函数。调用虚函数指针或引用运行时解析有两种类型:动态和静态。这里有动态类型和静态类型,只有在运行时才知道动态类型。Quote base;print_total(cout, base, 10); //调用Quote::net_...原创 2019-04-27 16:26:56 · 147 阅读 · 0 评论 -
引用限定符
动机允许向右值赋值有时会出现不可思议的语句。string s1 = "aa";string s2 = "aa";s1 + s2 = "cc"; //左边是右值,也是对的无法阻止这种限制,就只能强制阻止了做法1.只能向左值赋值一些情况2.只能向右值赋值后面加&&就行。...原创 2019-04-22 23:16:15 · 735 阅读 · 0 评论 -
移动构造和移动赋值运算符
定义只是自动帮你调用析构。得自己确保写对这个函数。比如把指针指向清0,让移后源对象达到一个安全的可析构状态。strVec::strVec(strVec &&) noexcept:elements(s.elements), first_free(s.first_free), cap(s.cap){ s.elements = s.first_free = s.cap...原创 2019-04-22 23:02:46 · 721 阅读 · 0 评论 -
delete阻止拷贝
动机有时我们不想对象可拷贝,比如iostream对象,可能想到的方式是不去定义,但赋值运算符和拷贝构造函数编译器帮我们默认定义了。只能显式说明一下。struct noCopy{ noCopy() = default; noCopy(const noCopy&) = delete; noCopy& operator=(const noCopy&am...原创 2019-04-22 15:36:47 · 151 阅读 · 0 评论 -
vector常见错误:缓冲区溢出
刚初始化一个vector对象时,注意其capacity和size的大小 。容量太小而去操作会造成缓冲区溢出。#include <iostream>#include <vector>#include <string>using namespace std;int main() { vector<int> ivec; ...原创 2019-03-28 12:45:44 · 2288 阅读 · 0 评论 -
函数指针(需精确匹配)
使用函数指针取址和使用都有两种方式#include <iostream>#include <vector>#include <string>using namespace std;bool lengthCompare(const string&, const string&){}bool (*pf)(const string...原创 2019-04-01 15:07:12 · 180 阅读 · 0 评论 -
sizeof运算符
不是函数sizeof是一种运算符,不是函数,就像+(-1)什么的,和+一个道理sizeof特殊之处1. 用于指针时,指的是指针本身所占大小。int ia[3][4];cout<<sizeof(ia+2)<<endl; //8 把ia + 2当成一个指针运算,所以ia+2整体是一个指针int(*)[4]2. 用于数组时,对数组中每个元素进行sizeo...原创 2019-03-31 10:29:19 · 106 阅读 · 0 评论 -
auto关键字
auto与基本类型1.注意推导的类型要能是同一种类型auto i = 0, *p = &i; //正确auto sz = 0, d = 3.13; //xxx,推导的不一致与复合类型1.auto后不加&或*号(1).后跟引用变量时 :直接看指向的对象,不是看引用本身int i = 0, &r =i;auto a =r; //推导为...原创 2019-03-26 23:57:09 · 119 阅读 · 0 评论 -
constexpr修饰符
常量表达式如果在编译阶段就能知道确切值,就是常量表达式,一部分const语句是,不是全部。const int ci = 42; //是const int ci2 = ci+1; //是int j = 1; //不是,就不是一个常量const int size = getSize(); //不是,运行时期才能确定constexpr1.作用验证是否是常量表达式,...原创 2019-03-26 22:43:24 · 329 阅读 · 0 评论 -
const关键字
基本原则1.只能初始化一次const int &ci = 512;ci = 0; //xxx2.const必须被初始化const int k;const与变量1. const与变量可以互相随便赋值int i = 42;const int ci = i;int j = ci; 解释:这里面是拷贝的关系,所以互相可以const与引用...原创 2019-03-26 21:53:02 · 119 阅读 · 0 评论 -
类里的一些特性
注意的几点1.可以在类里定义类型别名,受访问级别约束。class Screen{ public: typedef string::size_type pos;};class Screen{ public: using pos = string::size_type;};2.成员函数声明为inline时,声明和定义里有一个...原创 2019-04-03 21:50:31 · 111 阅读 · 0 评论 -
指针
基本指针1,指针不能用变量初始化。可以用字面值常量初始化int zero = 0;int *pi = zero; //直接报错2. 定义多个指针变量int *p1, p2; //xxx,p2不是指针int *p1, *p2; //这样才对3. 指向指针的指针int ival = 1024;int *pi = &ival; //一级指针int **p...原创 2019-03-26 14:09:17 · 62 阅读 · 0 评论 -
引用
普通引用1. 引用必须被初始化int &refVal2; //xxx2.引用只是别名,不是对象,所以不能定义引用的引用//引用的引用是指类似"指针的指针"那样//比如指针int i=0;int *p1=&i;int **p2=&p1;//p2是指向指针变量的指针//但对于引用int c;int &b=c;int &a=b...原创 2019-03-26 14:09:43 · 87 阅读 · 0 评论 -
概念:初始化和赋值,定义和声明
初始化和赋值在C++中,初始化和赋值是不一样的。初始化是指在定义的同时进行赋值,而赋值是指擦除老值。double price = 109.99; //先定义一个变量再进行初始化定义和声明1.定义就是分配内存,声明没有 。extern int i; //只做了声明int j; //定义2.有初始化的声明就是定义extern double pi = 3....原创 2019-03-26 13:09:30 · 901 阅读 · 0 评论 -
类型转换
基本类型转换(见2.1节)1.无符号数与有符号数的运算1) 一般无符号数和有符号放一起,有符号会转换为无符号,所以要避免它俩混用#include <iostream>using namespace std;int main() { unsigned u; u = 10; int i=-42; cout<< u + i&l...原创 2019-03-26 12:28:28 · 118 阅读 · 0 评论 -
decltype关键字
用于函数不实际调用函数,只是用返回值的类型#include <iostream>using namespace std;int f(){ return 0;}int main() { decltype(f()) a=0; return 0;}用于普通变量用于引用int i=0, &r = i, *p = &a...原创 2019-03-27 13:09:06 · 100 阅读 · 0 评论 -
命名空间
目的把函数限制在某个空间,防止同名函数冲突,每个人都可以定义自己的空间,实在冲突就在函数前加上不同的空间就行可以分着引using std::cin;using std::cout;using std::endl;也可以一下子引using namespace std;...原创 2019-03-27 13:20:42 · 73 阅读 · 0 评论 -
函数匹配(需最佳匹配)
规则1、选择可行函数集2、寻找最佳匹配3、找到就结束,找不到二义性错误。void f();void f(int);void f(int,int);void f(double,double = 3.14);f(5.6); //f(int)最合适f(42, 5.6); //void f(int,int)和void f(double,double = 3.14) 都行。...原创 2019-04-01 14:13:39 · 403 阅读 · 0 评论 -
constexpr函数
定义constexpr函数的规则:1、形参和返回值类型都是字面值类型(基本类型)2、函数体有且只有一条return语句。constexpr int new_sz(){ return 42;}constexpr size_t scale(size_t cnt){ return new_sz()*cnt;}不一定返回常量表达式所有对象都是字面值常量,才...原创 2019-04-01 14:03:13 · 509 阅读 · 0 评论 -
从vector看列表初始化
C++11新标准提供的,可以在数组中同时初始化多个对象vector<string> v1 = {"a","an","the"};vector<string> v2{"a","an","the"};C++无法列表初始化时会尝试其他方式。这样感觉挺乱套的vector<string> v7 = {10}; //初始化10个默认初始化的元素v...原创 2019-03-28 12:41:09 · 2995 阅读 · 0 评论 -
函数重载
基本原则只看形参类型不同即可,不看返回值类型Record lookup(const Account &);bool lookup(const Account &); //xxx,返回类型不同没用原则1顶层const不能区分形参,因为只是拷贝。Record lookup(Phone);Record lookup(const Phone); //xxx...原创 2019-04-01 13:44:21 · 63 阅读 · 0 评论 -
函数返回值(包含const返回值解析)
如何返回值1.返回值非引用primer说函数返回值用于初始化函数调用点的一个临时对象,所以返回值到临时对象是第一次拷贝,临时对象到接收值的变量是第二次拷贝。string make_plural(size_t ctr, const string &word, const string &ending){ return (ctr > 1) ? word :...原创 2019-04-01 11:16:08 · 6239 阅读 · 0 评论 -
函数形参(指针,引用,const,数组形参)
指针形参指针也是对象,也会拷贝,所以分实参指针和形参指针。在传进函数时,实参进行拷贝,所以在函数里改变指针值不影响实参。void reset(int *ip){ *ip = 0; ip = 0; //只改变了形参}引用形参引用不是对象,通过引用可以改变实参void reset(int &i){ i = 0; //改变了实参}使用...原创 2019-03-31 21:54:54 · 2210 阅读 · 0 评论 -
static成员
类定义class Account{public: static double rate(){ return interestRate; }private: static double interestRate; static double initRate() { return 1; }};doub...原创 2019-04-05 15:00:53 · 327 阅读 · 0 评论