在成员函数中,我们可以修改this的属性,(this 是指向非常量的常量指针)
std::string sales_data::isbn(const sales_data *const this);
成员函数可以随意使用成员变量,编译器先编译变量。
读入操作会改变流的内容,一般来说执行输出任务的函数应尽量减少对格式的控制,这样可以由用户**来决定是否换行。
构造函数不能声明成const
编译器自己创建的构造函数叫合成的默认构造函数。
当我们定义了其他的构造函数编译器不在合成默认构造函数,只有当类没有任何构造函数时,编译器才会自动生成默认构造函数。
合成默认函数可能执行错误操作,含有内置类型或复合类型成员的累应该在类内部初始化这些成员,或者定义一个默认初始化函数。
成员包含没有默认构造函数的类,无法合成默认构造函数。
还有其他情况)
在c++11中,如果我们需要默认构造函数可以写成,sales_dsata() default;
default 可以放在函数内部(内联),也可以放在函数外部(非内联)
包含vector或string成员的类,其拷贝,赋值,销毁的合成版本可以正常使用。
struct默认访问时public,class是private
最好在类定义带式或结束前的位置集中声明友元函数。
友元的声明仅仅指定了访问权限,所以要在别的地方重新声明。
typedef std::string::size_typpe pos;
#denfine n 10
将成员变量声明成 mutable 我们就可以再const成员函数内修改变量了。
当我们提供一个类内初始值时,必须以 = 或花括号表示。
一个const成员函数如果以引用的形式返回*this,那么它的返回类型将是常量引用;
非常量版本对于常量是不可用的。
多使用类内的内联私有小函数,使类设计更清楚,降低复杂程度,方便调试。
每个类定义了唯一的类型,就算成员完全一样,两个类也不同。
在类声明而未定义时,叫不完全类,使用有限:可以指向类的引用、指针,也可以声明(但不能定义)以不完全类型作为参数或返回值的函数。
知道类被定义之后数据成员才能被声明成这种类类型,但是,类允许包含指向它自身类型的指针或引用。
class screen;
对于类,首先,编译成员的声明,直到类全部可见后才编译函数体,在类声明中定义的函数体也是。
所以函数体可以使用类中任何定义的名字,在类中,如果成员使用了外层作用域的某个名字,而改名字代表一种类型,则类不能再之后重新定义该名字。
类型名的定义一般出现在开始。
在成员函数中如果有与成员变量一样的名字,函数中的将屏蔽成员变量,但是我们可以通过this 访问。
在考虑全局作用域时,不仅有类前的作用,还有成员函数的之前的全局域。
对于const 和引用的初始化应该采用初始化列表,因为随着构造函数一开始执行,初始化就完成了、
构造函数初始化列表只是用于说明初始化成员的值,而不限定初始化的具体顺序。
成员函数的初始化顺序与他们在类中定义的顺序一致,因此最好然初始化列表中的顺和变量定义的顺序一致。
对于构造函数参数中有默认值时,实际上是提供了默认的构造函数的。
委托构造函数:
class sales_data
sales_data():sales_data(" 0 , 0)
sales_data(std::istream &is):sales_data()
后两个就是委托构造函数,先执行的是受委托函数体中的**,然后才将控制全交给委托函数。
默认构造函数在变量定义是自动调用,不要显示的去调用默认构造函数(不要给默认构造函数后加括号)
当对象被默认初始化或值初始化时自动执行默认构造函数。
默认初始化在一下情况发生:
当我们在块作用域内不使用任何初始值定义一个非静态变量或数组时;
当一个类本身含有类类型的成员且使用的是合成默认构造函数。
当类类型的成员没有在构造函数初始化列表中显示的初始化时。
值初始化发生在以下情况:
在数组初始化的过程中如果我们提供的初始值数量少于数组大小时。
当我们不使用初始值定义一个局部静态变量时。
当我们通过书写形如t()的表达式显示地请求初始化时。
合成默认构造函数,如果存在类内值初始化,则用它初始化,否则使用默认初始化。
能通过一个实参调用的构造函数定义了一条从构造函数的参数类型向类类型隐式转换的规则。
就是当需要一个类类型时,我们可以使用一个别的类型(只有一个参数的构造函数中的类型)来转换。
只允许一步类类型转换。
抑制构造函数定义的隐式转换:我们可以通过将构造函数声明为explicit,只对有一个实参的构造函数有效。
只能在直接初始化中使用explicit构造函数,不能在拷贝初始化中使用。
explicit的构造函数不会用于隐式转化过程,但是我们可以使用强制类型转换。
cin) )
在标准库中,接受一个单参数的const char*的string构造函数不是explicit
接受一个容量参数的vector构造函数式explicit的。
聚合类:所有成员都是public的,没有定义任何构造函数,没有类内初始值,没有基类,也没有virtual函数。
struct data ; 聚合类的初始化,顺序不能变,如果提供的参数少于变量,那么执行值初始化。
对于字面值类型的类,可能含有constexpr函数成员,这样的成员必须符合constexpr函数的所有要求,它们是隐式const的。
数据成员都是字面值类型的聚合类是字面值常量,如果一个列不是聚合类,但它符合下述要求,他也是一个字面值常量类:
数据成员都必须是字面值类型,类必须至少含有一个constexpr构造函数。
如果一个数据成员含有类内初始值,则内置类型成员的初始值必须是一条常量表达式;或者如果成员属于某种类类型,则初始这必须使用成员自己的constexpr构造函数。
类必须使用析构函数的默认定义,该成员负责销毁类的对象。
构造函数不能使const的,但是,字面值常量类的构造函数可以是constexpr函数。事实上,一个字面值常量类必须至少提供一个constexpr构造函数,它可以声明成default(或者是删除函数的形式)否则,它必须既符合构造函数的要求(无返回语句)又符合constexpr函数的要求(只有返回语句),那么constexpr就是空的函数体了,constexpr debug(bool b=true): hw(b),io(b),other(b)
constexpr构造函数必须初始化所有数据成员,初始值或者使用constexpr构造函数,或者是一条常量表达式。
constexpr构造函数用于生成constexpr对象以及constexpr函数的参数或返回类型。
constexpr debug io_sub(false,true,false);/定义个debug类类型的变量。
我们通过在成员之前加上关键在static使得其与类关联在一起。
类的静态成员存在于任何对象之外,对象中不包含任何与静态数据成员有关的数据。
静态函数也不与任何对象绑定在一起,它们不包含this指针,因此,静态成员函数不能声明成const的,而且也不能再static函数体内使用this指针,这一限制适用于this的显示使用,也对调用非静态成员的隐式使用有效。
我们使用作用域访问符::直接访问静态成员。
虽然静态成员不属于类的某个对象,但是我们仍然可以使用类的对象、引用或指针来访问静态成员。
对于成员函数不用使用作用域访问符就可直接访问静态成员。
当在类的外部定义静态成员函数时,不能重复使用, 这个关键字只能出现在类内部。
因为静态数据成员不属于类的任何一个对象,所以,它们并不是在创建类的对象时被定义的,它们不是由类的构造函数初始化的,一般,我们不能再类的内部初始化静态成员。必须在类的外部初始化每个静态成员,和全局变量一样,静态函数成员定义在任何函数之外。因此一旦定义就一直存在。
C11学习笔记 5
参数传递时,如果是引用类型,它将绑定到对应的实参上,否者,将实参的值拷贝后赋给形参。引用可避免拷贝,如果不需要改变参数,最好定义成常量引用。和其他初始化一样,当用实参初始化时会忽略顶层const,当形参有顶层const时,传给它常量对象或非常量对象都可以。我们可以用非常量初始化一个底层const对象...
C 11学习笔记 11
动态分配的内存,只有在显式释放是,这些对象才会销毁。但是标准库中的两智能指针可以确保自动释放。除了静态内存和栈内存,每个程序还拥有一个内存池。这部分内存被称作自由空间或堆。静态内存用来保存局部static对象 类static数据成员以及定义在任何函数之外的变量。栈内存用来保存定义在函数没得非stat...
C 11学习笔记 16
tuple是类型pair的模板。不同tuple类型的成员类型也不同,但一个tuple可以有任意数量的成员。每个确定的tuple类型的成员数目是固定的。当我们希望将一些数据组合成单一对象,但有不想麻烦地定义一个新数据结构来表示时,tuple是非常有用的。快速而随意 的数据结构 tuple类型及其伴随类...