main()
函数由启动代码调用,它是由编译器添加到程序中的。endl
可以刷新输出,而\n不能保证。使用dec、oct、hex
来输出不同进制数据。using
编译指令、using
声明指令,::
为作用域解析运算符,尽量使用声明。short
至少16位;int
至少与short
一样长;long
至少32位,且至少与int
一样长;long long
至少64位,且至少与long
一样长。e.g. int a{1}; ==> int a=1;
C11(typename) value
来自C语言。typename(value)
纯粹的C++格式。static_cast<typename> (value)
。reinterpret_cast
是进行高风险转换,比如整型转换成指针,但不能将函数指针转换成数据指针。const_cast
可以改变值为const
或volatile
,一般在需要删除const
标签时使用。但原来的值并不能真正被修改,虽然都是指向相同的地址。dynamic_cast
cin
读取一个单词,cin.getline()
读取整行并删除换行符,cin.get()
读取整行并保留换行符到输入序列。wchar_t
类型,L"xxxxx",16位~32位 经测试ubuntu为32位char16_t
类型,u"xxxxx",16位 C++11char32_t
类型,U"xxxxx",32位 C++11malloc
相似,C++用new
用来申请内存,释放内存用delete
。delete
只会释放指针指向的内存,不会删除指针本身,即指针本身可以重复使用去指向另一个新分配的内存。只能用于释放new
申请的内存,不要用于释放声明变量所获得的内存,也不要重复释放相同内存块。vector
模板类,是一种动态数组。array
(C++11)模板类,与数组相同,是静态内存分配(放在栈中)。fstream
ofstream或ifstream
。cout或cin
那样使用它。inline
。一般直接在声明出直接定义。不可以递归,否则编译器会认为常规函数。const
指针。const
可以生成临时变量再引用,此时可以转换类型),允许被调函数访问主调函数的变量。当然用指针也可以实现。节约时间和内存。typename
、class
来声明参数类型。template<>
为显式具体化、template
为显式实例化。decltype
用在函数模板中,提供参数的类型。auto
和decltype
结合使用,定义模板函数。C++11new
运算符,可以指定要使用的位置。需要包含new
头文件。int *p = new (buffer) int;
new
等关键字自己分配的,直到自己delete
或者程序结束。inline
也可以成为内联函数。const
关键字,表示类方法不会修改调用对象,称为const成员函数。不是类成员函数不允许在后面加const
。this
指针指向调用成员函数的对象(被作为隐藏参数传递给方法),注意this是指针,*this
是该对象,与java不同。每个成员函数都有一个this
指针。static const
来创建一个所有对象共享的常量。operatorop()
来重载运算符,op是运算符。如operator*()
,*
将被重载。掉用方法时可以使用运算符表示法,符号左侧是调用对象,右侧是参数。也可以使用常规的形式调用方法。friend
关键字)成为类的友元,可以赋予该函数与类成员函数相同的访问权限,如访问私有变量。explicit
时将屏蔽这种隐式转换,此时值能进行显式转换。也就是利用构造函数可以将某种类型转换成类类型。operator typename()
即可自动调用。C++11中可以加上explicit
关键字,将不会隐式转换,只能显式转换(注意C++98中不允许explicit
加在函数前面)。explicit
只能处于类函数原型中,定义时不加。
static
修饰),所有对象都将只创建一个静态类变量副本。不能在类声明中初始化静态成员变量。当静态数据成员为const
整数类型或者枚举型时可以在声明时初始化。nullptr
来表示空指针。String::HowMany()
。const
常量数据和被声明为引用的类成员初始化时,需要在构造函数右边进行初始化,这会在创建对象前初始化,其他参数也可以。不过成员初始化列表语法只能用于构造函数。virtual
只用于函数原型,不用于定义中。new
时,默认的构造、复制、赋值、析构函数是能正常处理的。new
时,将按下面操作自行定义:
const
来避免被修改。const
可以确保不修改参数,放在后面可以确保不修改它的对象。explicit
关键字,防止隐式转换。private
进行继承(默认)。
protected
进行继承。using
重新定义访问权限。virtual
关键字。::
来区分。若使用虚基类,该方法不能叠加。template<class Type>
,表示是模板类;加在成员函数上方,表示是函数模板。可以用作基类。template<class Type,int n>
,class
等价于typename
,表达式参数可以是整型、枚举、引用或指针,另外用作表达式参数n的值必须是常量表达式。使用表达式参数的方法的缺点主要是,每次改变n的值都会生成自己的模板,因此使用构造参数更通用。template class Classname<T>;
template <> class Classname<specialized-tyep-name>{...};
,当具体化模板与通用模板都与实例化请求匹配时,使用具体化版本。目的是对模板进行修改,使其行为不同。//采用嵌套的方式 template<typename T> template<typename V>
template<template<typename T> class Thing> class Crab{ }
其中template<typename T> class
是类型,Thing
是参数,类中可以使用Thing<int>
等作为模板参数的实例化。
typdef xx newname
和using newname = xx
来设定别名。friend class classname
可以放在公有、私有、保护位置,友元类的声明与位置无关。void onoff(){state=(state==on)? Off : On;}
,若两种状态分别为true(1)和false(0),则可以用异或和赋值运算符简写,void onoff(){state ^= 1;}
try{...}catch( ){...}
,catch
可以捕获字符串,但通常是类类型(使用类引用)。void test(int a) throw()
),作用之一是告诉用户可能需要使用try块,另一作用是让编译器添加运行阶段检查代码,检查是否违反了异常规范。noexcept
指出函数不会发生异常(C++11)。terminate()
,terminate()
再调用abort()
;若发生异常规范中没有的异常(也没有std::bad_exception类型,否则会被改该类型替代
),则调用unexpected()
,它会去调用terminate()
。若不想程序终止,则应该重写上述方法。exception
异常类在头文件exception
中,可以用它作为其他异常类的基类,what()
虚函数可以返回一个字符串。stdexcept
中定义了一些异常类,如logic_error
等。通过catch
不同的类名,可以实现分别处理异常;在具备继承关系的异常类中,可以实现一起处理。(要求catch块从派生类开始,一直到基类,再到上一层的基类的顺序排放)bad_alloc
异常可用于捕获new
分配时的异常,头文件new
中包含了该类的声明。由于之前的new
是返回空指针,所以C++提供了一个标志,让用户选择。int *pi = new (std::nothrow) int;
与int *pa = new (std::nowthrow) int[500];
。new
、malloc
等关键字(堆内存管理),提前出现异常将导致内存泄漏(需要在catch中进行清理内存操作,或者使用智能指针模板)。dynamic_cast
运算符,可以回答“是否可以安全的将对象的地址赋值给特定类型的指针”这样的问题。dynamic_cast<type *>(pt)
,如果可以将对象地址转换成指向type
的地址,则返回该,否则返回空指针。也可以用于引用,当无法强制转换时,将引发bad_cast
异常,需要头文件typeinfo
。typeid
运算符,返回一个type_info
对象。type_info
类,在头文件typeinfo
中,其成员函数name()
将返回该类的名称。该类重载了==
和!=
,所以可以确定两个对象是否为相同类型。string
构造函数,7个。输入方法2种。auto_ptr
(C++98提出,C++11已经废弃),unique_ptr
(C++11),shared_ptr
(C++11)。必须包含头文件memory
,位于名称空间std
中。不可以用于堆内存。//auto_ptr模板函数如下 template<class X> class auto_ptr{ public: explicit auto_ptr(X *p=0) throw(); ... } //使用 auto_ptr<double> pdu(new double);//获得一个指向double的auto_ptr
delete
两次对象的方法
auto_ptr
和unique_ptr
采用这种方法。delete
,shared_ptr
采用这个方法。auto_ptr
在将指针所有权给别人后,不可以再使用该指针。unique_ptr
会在编译阶段控制这种错误(auto_ptr
中的错误),但当unique_ptr
是一个临时右值时编译器不会报错,因为不会产生悬挂指针。使用std::move()
可以将一个unique_ptr
赋值给另一个unique_ptr
。当使用new[]
分配内存时,只能使用unique_ptr
.shared_ptr
。operater*()
)和递增(operater++()
)的对象。vector<double> scores; vector<double>::iterator pd=scores.begin(); //迭代器类似于指针 *pd=22.3; pd++;
operator++()
作为前缀版本,operator++(int)
作为后缀版本。课后练习题答案