一,友元
友元函数:
友元函数在类里面声明只是告诉编译器说,我现在有一个函数是类的友元,但这只是友元的声明!
不是函数的声明!!就算你在类里面给出了这个友元函数的定义,也只是友元的声明!!
所以如果在成员函数里面调用友元函数,则必须在类外再次声明一次这个友元函数,
举个例子:
就算你给出了友元的定义,没用!只算友元声明!!
解决方法就是再声明一次!
虽然这里报了警告,但是只要实现友元函数就行了!!在类里面直接实现友元或者到外面.cpp实现也行
二,this的一些细节
假设有一个类叫Class,那么其【非static】成员函数的this指针类型就是Class * const类型,
常量指针,顶层const,没有底层const
mutable
这个关键字修饰的成员变量,即使在const成员函数里面,该函数也可以修改这个mutable变量
举个例子:下面fun是const成员函数,但由于value是mutable修饰,所以value可以更改
但是对height的修改则是非法的,因为height没有mutable修饰!!
class Foo{
private:
mutable int value;
int height;
public :
void fun()const{
++value;
//++height;则是非法的
}
}
三,构造函数
初始化列表语法和在构造函数里面赋值究竟又什么区别???
在初始化列表里面是叫做【初始化】成员!!
构造函数里面设置(或者叫赋值)成员,那就是从随机值到指定值的过程了!!
因为【构造函数体】一旦【开始执行】,成员的初始化就已经完成了,如果你在函数
体里面这个时候才对成员指定值,那么这只能叫【赋值】,而不能叫【初始化】了;
初始化列表语法,则是直接指定初始值,直接就是用你给定的初始值,初始化成员
(Ⅰ)编译错误:
常见的一些编译错误通常来自于const和左值引用成员的初始化问题!!
第19行的初始化列表语法可以很好地解决该问题
(Ⅱ)初始化成员的顺序
原则
按照成员的声明先后顺序,先声明,先初始化
如果你使用初始化列表语法,不按照声明顺序初始化,那么就会导致随机值的成员!!
举个例子:编译器一般给出警告!!不要忽视编译器的每一个警告!!!
(Ⅲ)委托构造函数
用初始化列表语法调用其他的构造器
一个构造函数调用另外一个受委托的构造函数,那么这个调用另外的构造函数的构造函数就叫做
委托构造函数,注意,【委托构造函数】可以接着调用【委托构造函数】,
初始化的顺序:
先执行受委托的构造函数的初始化列表,受委托的构造函数的代码,执行完了,再回到委托构造函数
里面执行其初始化列表,再执行其剩下的代码
(Ⅳ)只允许1步的类类型转换
#include <iostream>
using namespace std;
class Foo {
private:
string m_name;
public:
Foo(string s,int i) {
}
Foo() {
}
void copy(Foo f) {
}
};
int main() {
Foo f;
f.copy("123");
}
不允许多步转换,只能进行1步转换!!
这里的"123"转化成为了string类型,string类型又可以转化成Foo类型,编译器禁止这种行为