第七章
1
成员函数的声明必须在类的内部,定义可以在外部。
定义在类内部的函数是隐式的inline
函数。
2
f()const{}
常量成员函数,类中的时候,表示this
是一个指向常量的指针,所以不能修改。
3
输入输出会改变流的内容,所以函数调用流的时候,不能使用对常量的引用。
构造函数
Sale_data()=default
,表示我们既需要合成的默认构造函数,也需要自己定义的。
(如果=default
出现在类的内部,则默认构造函数是内联的。/只要在类内定义了函数,就是隐式内联)
Sale_data(int x,int y):xx(x),yy(y){}
:中间部分是构造函数初始值列表,如果变量不是类内全部变量,其他的会以合成的构造函数相同的方式隐式初始化。
4
struct
关键字和class
都可以定义类,但class
在遇到第一个访问说明符之前都是private
,而class
是public
.
一般来说,作为接口的一部分,构造函数和一部分成员函数应该定义在public说明符之后,而数据成员作为实现部分的函数则应该跟在private说明符之后。
5
封装的优点:易于修改扩展功能、不易破坏。
6
友元可以允许其他类和函数访问它的非公有成员。
就算类内函数声明没有加内联,定义的时候也可以加。
声明加了,定义的时候可以不加。
7
如果我们需要在const
函数中修改某个变量,需要声明这个变量为mutable
例如:mutable size_t access_ctr;
8
底层const
形参可以重载函数,同理返回值const
也可以重载函数。
const Screen &display(std::ostream &os)const{
do_display(os);return *this;
}
9
对象声明:
Sales_data item1;
class Sales_data item2;
类的声明可以和定义分离:
类的声明——class Screen;
10
友元不具有传递性,友元的友元不是友元。
一组重载函数要声明为友元,需要对每一个分别声明。
友元函数声明过后,函数也需要声明。
11
定义类函数的时候,只需要在名字加上类的作用域即可:
函数里面可以直接用作用域里的值,但是返回值不能直接用,因为不在作用域里。
12
内层作用域可以重新定义外层作用域的名字,即使已经使用过。
但对于类来说不行(一旦使用了,就不行)
13
有些时候类的构造函数必须为某些变量(引用/常量)提供初始化
类的初始化列表的初始化顺序和在类中定义的顺序一致,而不是初始化列表的顺序
14
委托构造函数就是把自己的职责委托给了别人
Sales_data(std::istream &is): Sales_data(){read(is,*this);}
类类型是可以自动转化的,但是只允许一步类型转换。
void combine(Sales_data Ss);combine("111");
是不合法的,因为字符串常量到string
是一步,string
到类也是一步(类有构造函数通过string
)
抑制这种隐式转换可以利用explict
,同时多个实参也不能执行隐式转换,并且explict
只能用于出现在类内部的构造函数声明处。
explict
的构造函数只能用于直接初始化。
不过我们仍然可以进行强制转换Sales_data(str);static_cast<Sales_data>(str);
15
直接使用f(Sales_data)
,会产生一个临时对象。
16
聚合类:
{
所有用户可以直接访问其成员;
没有定义任何构造函数;
没有类内初始值;
没有基类,也没有virtual
函数。
}
可以用花括号包起来的初始化列表,用于初始化聚合类成员。
字面值常量类:
数据类型都是字面值类型的聚合类是字面值类
或者:
17
在外部定义静态成员的时候,不能重复static
。
类的静态成员必须在类外部初始化,除非是常量成员(constexpr
),但如果要传引用的话,需要在外部再次定义。
静态成员可以用于类内默认实参,可以是不完全类型class A{static A B;}
到这里,第一部分就看完了,准备复习一遍再看后面的,而且看后面的之前想把其他的计算机基础补好。