C++笔记(一)

1、成员函数末尾带const : 不会修改该对象里任何成员变量的值

void noone() const {
  Hour += 10;  //错误,常量成员函数不可以修改稿成员变量的值
}

2、mutable 修饰符来修饰一个成员变量,这个成员变量处于可变状态,即使是以const 结尾的成员函数中也能修改。

mutable int Hour;
void noone() const {
  Hour += 10;  //可以修改成员变量Hour了。
}

3、static 修饰的成员变量(静态成员变量),在类中声明但没有定义,未分配内存,需要正在cpp源文件头定义来保证任何调用函数之前这个静态变量已经被初始化

// .h 文件中
public:
  static int mystatic;                      //声明静态成员变量但没有定义
  static void mystaticfunc(int testvalues); // 声明静态成员函数
  
// .cpp文件中
int Time::mystatic = 5; // 可以不给初始值,默认为0,定义时不要加static

4、= default : 编译器自动生成函数体,等价于 {}, 只适用于特殊的构造函数。 = delete :显式的禁用某个函数

5、拷贝构造函数:如果一个类的构造函数的第一个参数是所属的类类型引用,若有额外的参数,那么这些额外的参数都有默认值,如果定义了自己的拷贝构造函数,那么就取代了编译器合成的拷贝构造函数,这个时候就必须在自己的拷贝构造函数中给类中成员逐个赋值,第一个参数带const,不带explicit修饰。

Time myTime;               //这会调用默认构造函数(不带参的)
Time myTime2 = myTime;     //调用了拷贝构造函数
Time myTime3 ( myTime);    //调用了拷贝构造函数
Time myTime4 { myrine };   //调用了拷贝构造函数
Time myTime5 = ( myTime};  //调用了拷贝构造函数
Time myTime6;              //这会调用默认构造函数(不带参的)
myTime6 = myTime5;         //没有调用拷贝构造函数

// 拷贝构造函数
Time::Time(const Time& timem, int a)

6、函数遮蔽:子类中如果有一个同名函数,那么父类中不管有几个同名函数,子类中都无法访问,如果我们确实想调用父类中的同名函数,有如下方法:

// (1)在子类的成员函数中用“父类::函数名”强制调用父类函数
// (2) 使用using,通过using让父类的同名函数在子类中可见
public:
      using Human::sameNameFunc:   // 只能指定函数名

7、基类中某个函数声明为虚函数,则所有子类中它都是虚函数。父类指针指向子类对象,调用子类同名同参函数,则需要把父类这个函数声明为虚函数(virtual)

Human *human = new Men;
human->eat(); //如果父类eat声明为virtual,则调用的是子类Men的eat函数
human->Human::eat(); // 如果函数前加了父类命名空间,则直接调用父类中的eat,即使父类声明为virtual。

8、为了避免在子类中写错虚函数,在C++11中,可以在子类函数声明中加override(虚函数专用),子类覆盖父类的同名同参函数,编译器进行纠错。
9、final 也是虚函数专用,用在父类中,如果我们在父类的函数声明中加了final,那么任何尝试子类覆盖父类的该函数都会失败
10、纯虚函数:在基类中声明的纯虚函数,要求子类中去实现。一旦一个类中有纯虚函数,就不能生成这个类的对象了,这个类成为了“抽象类”

// 1)抽象类不能生成对象,统一管理子类对象
// 2)子类中必须要实现该基类中定义的纯虚函数
virtual void eat() = 0; // 没有函数体,只有声明

11、当定义一个子类对象时,先执行的是父类的构造函数体,再行子类构造函数体,当对象被系统回收时,先执行子类的析构函数,再执行父类的函数体。
12、用基类指针new子类对象,在delete的时候系统不会调用子类的析构函数,需要把父类的析构函数声明为虚函数才行 - 虚析构函数

Human *human = new Men;
delete human; // 没有执行子类的析构函数

// 修改父类析构函数:
virtual ~ Human();

// 1)如果一个类想要做父类,务必要把这个类的析构写成virtual
// 2)普通类可以不写析构函数,但如果是基类,就必须写一个析构函数,必须是虚析构函数
// 3)虚函数会增加内存开销,类里面定义虚函数,编译器就会给这个类增加虚函数表,这个表中存放虚函数地址等信息

13、每个类都负责控制自己的友元类和友元函数,友元类关系的判断,最終还是要看类定义中有没有对应的friend 类声明:
(1)友元关系是不能被子类继承的。
(2)友元关系是单向的,比如类B是类A 的友元类,但这并不表示类 A是类B的友元类。
(3)友元关系也没有传递性,例如类B是类 A的友元类,类C是类 B的友元类,这并不代表类 C是类 A的友元类。

Class A
{
      friend class B; // 不需要public、protected、private 修饰
  private:
      int data;
};

14、RTTI(Run Time Type identification):运行时类型识别
(1)dynamic_cast: 能够将父类指针或引用安全的转换为子类的指针或引用,帮助开发者做安全检查

Human *phuman = new Men;
Men *pman = dynamic_cast<Men *>(phuman);
if (pman != nullptr) {
  cout<<"转换成功"<<endl;
} else {
  cout<<"转换失败"<<endl;
}
// 对于引用,如果转换失败,则系统会抛出std::bad_cast异常,try...catch(){}
Human *phuman = new Men;
Human &q = *phuman;
try {
  Men &pman = dynamic_cast<Men &>(q);
  cout<<"转换成功"<<endl;
} catch(std::bad_cast) {
  cout<<"转换失败"<<endl;
}

(2)typeid:返回指针或引用所指对象的实际类型,例如typeid(指针或引用),typeid(表达式),返回一个常量对象的引用(标准库类型(type_info))

Human *phuman = new Men;
const std::type_info& tp = typeid(*phuman);
cout<<tp.name()<<endl; // 父类有虚函数则结果为Class Men,否者为class Human

(3)要想RTTI两个运算符正常工作,那么基类中必须要有一个虚函数

// c++中,如果类里含有虚函数。编译器就会对该类产生一个虚函数表。
// 虚函数表里有很多项,每一项都是一个指针。每个指针指向的是这个类里的各个虚函数的入口地址。
// 虚函数表项里,第一个表项很特殊(有些编译器虚函数表第一项之前的内存位置存放指针,指向这个类所关联的type_info对彖),它指向的不是虚函数的入口地址,它指向的实际上是这个类所关联的type_info对彖
Human *phuman = new Men:
const std::type_info& tp = typeid(*phuman);
//phuman对象里有一个我们看不见的指针,这个指针指向的是这个对象所在的类Men里的虚函数表。

15、左值引用,一般不能绑定右值,只能绑定到左值上,const引用可以绑定到右值,const引用特殊。

char *p = nullptr ; // 指针有空指针说法,引用没有空引用说法,必须初始化,一般绑定左值。
int a = 1;
int &b{ a }        //b 绑定到a,当然可以
int &c;            //不可以,引用必须要初始化
int &c = 1;        //不可以,c要绑定到左值上,不能绑定到右值上
const int &c = 1;  //可以,const 引用可以绑定到右值上,所以const 引用可以说比较特殊
// 上面这段代码最后一行等价于下面这两行:
int tempvalue = 1;
const int &c = tempvalue //可以把 tempvalve 看成一个临时变量

16、右值引用,绑定到右值的引用,用“&&”,希望用右值引用来绑定到即将销毁的或是一些临时的对象上。C++ 11 引入目的是提高程序运行效率,将拷贝对象变成移动对象。

int a = 10;
int &c = 1;        //不可以,c要绑定到左值上,不能绑定到右值上
int &&c = 1;       //可以
int &&c = a;       //不可以,不能将右值引用绑定到左值上
const int &c = 1;  //可以

17、++i : 左值表达式, i++ : 右值表达式

++i 是直接给 i 变量加 1,然后返回i本身,因为i是变量,所以可以被赋值,因此是左值表达式。看看如下范例:
int i = 5;
(++i) = 20; 

i++先产生一个临时变量来保存i的值用于使用目的,再给 i加 1,接着返回临时变量,之后系统再释放这个临时变量,临时变量被释放掉了,不能再被赋值,因此是右值表达式。看看如下范例:
int i = 5;
(i++) = 20; //语法错误,提示:表达式必须是可修改的左值

18、std::move : 把一个左值 强制 转换成右值

int i= 10;
int &&r = i;  // 错误,不能将右值引用绑定到左值上
int &&r = std::move(i); // 正确

19、临时对象产生:

CTempValue sum;
sum = 1000; // 产生了一个临时对象
CTempValue sum = 1000; // 不会产生临时对象,为sum对象预留了空间,用1000构造sum对象,而且是直接构造在sum对象预留空间里。

20、移动构造函数:声明和实现习惯性加noexcept通知编译器该移动构造函数不抛出任何异常提高编译效率

A(A&& tempa) noexcept : m_pb(tempa.m_pb) {
    tempa.m_pb  = nullptr;
    std::cout<< "移动构造函数执行" << std::endl;
}

21、虚继承离不开虚基类,虚基类的特点就是无论这个类在继承体系中出现多少次,派生类中都只会包含唯一一个共享的该类子对象

class A : virtual public B {...}

22、显式类型转换运算符

explicit operator int() const {
  return m_i;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,458评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,454评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,171评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,062评论 0 207
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,440评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,661评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,906评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,609评论 0 200
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,379评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,600评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,085评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,409评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,072评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,088评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,860评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,704评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,608评论 2 270