您的位置:首页 > 编程语言 > C语言/C++

C++基础学习

2015-01-01 10:03 253 查看
一、C++中类作用域(即::)的作用:
1、标识作用域的级别 2、标识成员属于哪个类 3、 限定成员的作用范围 4、指出作用域的范围

二、C++纯虚函数
定义了纯虚函数使其成为抽象类,抽象类不可以定义对象,但可以定义纯虚函数(即可以实现改纯虚函数)。定义它的目的是其派生类中可以直接调用基类纯虚函数的某些功能。

三、类模板的静态成员
在包含静态成员变量的类模板中,按照C++标准的要求,将类模板静态成员变量的实现与类模板实现放在同一可见范围内,通常,将静态成员变量的实现写在类模板实现之后。

四、C++标准提倡将模板的所有实现都放在头文件中以便编译器可以当场实现模板实例。这样能够避免产生跨目标文件链接。

五、可以作为模板参数的非模板类参数
1)整数及枚举型
2)指向对象或函数的指针
3)对对象或函数的引用
4)指向对象成员的指针
(注:指针及引用模板参数相当于为函数或类声明一个常量指针或引用,且只有指向全局变量及外部变量(以extern修饰)及类静态变量的指针及引用才可作为模板参数)

六、模板特化
例子:
template<typename T> class my_vector; //my_vector模板通例
template<> classs my_vector<bool>; //my_vector模板特例

七、利用宏来写setter和getter函数
如:#define CC_PRIVATE(varType, varName, funName)\
private: varType varName;\
public: varType get##funName(void) const {return varName;}\
public: void set##funName(varType var) {varName = var;}

则CC_PRIVATE(int, m_iX, iX);
经过宏展开之后:
private: int m_iX;
public: int getiX(void) const{return m_iX;}
public: void setiX(int var) {m_iX = var;}

八、reinterpret_cast<type_id>(expression) 可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针。
注:type_id必须是一个指针、引用、算术类型、函数指针或者成员指针。

九、windows下输入long long型需要用%I64d,在linux下输入long long型需要%lld.

十、C++11新标准提供了两种主要方法来编写处理不同数量实参的函数:若所有的实参类型相同,可以传递一个名为initializer_list的标准库类型;若实参的类型不同,则可编写一种特殊的函数--可变参数模板。
1)若函数的实参数量未知但是全部实参的类型都相同,可使用initializer_list的类型的形参。initializer_list是一种标准库类型,用于表示某种特定类型的值的数组。initializer_list类型定义在同名的头文件中,initializer_list对象中的元素永远是常量值。
如:void error_msg(initializer_list<string> il)
{
for(auto beg = il.begin(); beg != il.end(); ++beg)
cout << *beg << " ";
cout << endl;
}
若想向initializer_list 形参中传递一个值的序列,则必须把序列放在一对花括号内:
if(expected != actual)
error_msg({"functionX", expected, actual});
else
error_msg({"functionX", "okay"});
2)可变参数模板---接受一个可变数目参数的模板函数或模板类。可变数目的参数被称为参数包,存在两种参数包:模板参数包,表示零个或多个模板参数;函数参数包,表示零个或多个函数参数。
// Args是一个模板参数包;rest是一个函数参数包
// Args表示零个或多个模板类型参数
// rest表示零个或多个函数参数
template <typename T, typename... Args> void foo(const T &t, const Args& ... rest);
声明了foo是一个可变参数函数模板,它有一个名为T的类型参数,和一个名为Args的模板参数包。这个包表示零个或多个额外的类型参数。
当我们需要知道包中有多少元素时,可以使用sizeof...运算符。如 template<typename ... Args> void g(Args ... args) { cout << sizeof...(Args) << endl; cout << sizeof...(args) << endl; }

十一、容器操作可能的迭代器失效
向容器中添加元素和从容器中删除元素的操作可能会使指向容器元素的指针、引用或迭代器失效。
(一) 在向容器添加元素后:
1)若容器是vector或string,且存储空间被重新分配,则指向容器的迭代器、指针和引用都会失效。若存储空间未重新分配,指向插入位置之前的元素的迭代器、指针和引用仍有效,但指向插入位置之后元素的迭代器、指针和引用将会失效。
2)对于deque,插入到除首尾位置之外的任何位置都会导致迭代器、指针和引用失效。若在首尾位置添加元素,迭代器会失效,但指向存在的元素的引用和指针不会失效。
3)对于list和forward_list,指向容器的迭代器(包括尾后迭代器和首前迭代器)、引用和指针仍有效。
(二)从一个容器中删除元素后
1)对于list和forward_list,指向容器其他位置的迭代器(包括尾后迭代器和首前迭代器)、引用和指针仍有效。
2)对于deque,如果在首尾之外的任何位置删除元素,那么指向被删除元素外其他元素的迭代器、引用或指针也会失效。若是删除deque的尾元素,则尾后迭代器也会失效,但其他迭代器、引用和指针不受影响;若是删除首元素,这些也不会受影响。
3)对于vector和string,指向被删元素之前元素的迭代器、引用和指针仍有效。
(注:当删除元素时,尾后迭代器总是会失效。

十二、智能指针 (在memory头文件中。)
(一)shared_ptr :允许多个指针指向同一个对象;
1)make_shared<T> (args) 返回一个shared_ptr,指向一个动态分配类型为T的对象。使用args初始化此对象。
2)shared_ptr没有提供"++"指针操作符。
3)接受指针参数的智能指针构造函数是explicit的,故不能将一个内置指针隐式转换为一个智能指针,必须使用直接初始化形式来初始化一个智能指针。如:shared_ptr<int> p(new int(1024));
4)注意:当将一个shared_ptr绑定到一个普通指针时,就将内存的管理责任交给了这个shared_ptr,一旦这样做了,就不应该再使用内置指针来访问shared_ptr所指向的内存。
5)智能指针类型定义了一个名为get的函数,它返回一个内置指针,指向智能指针管理的对象。其设计目的是为了要向不能使用智能指针的代码传递一个内置指针。使用get返回的指针的代码不能delete此指针。
且永远不要用get初始化另一个智能指针或者为另一个指针赋值。
6)shared_ptr是管理共享资源的利器,需要注意避免循环引用,通常做法是owner持有指向child的shared_ptr,而child持有指向owner的weak_ptr。
(二)unique_ptr :“独占”所有指向的对象。
1)unique_ptr不支持普通的拷贝和赋值操作
2)假设unique_ptr对象u,u.release()表示u放弃对指针的控制权,返回指针,并将u置为空。
3)同样对象u,u.reset()表示释放u所指向的对象,u.reset(q)表示若提供了内置指针q,则令u指向这个对象,否则将u置为空。
4)不能拷贝unique_ptr的规则有一个例外:可以拷贝或赋值一个将要被销毁的unique_ptr,最常见的例子是从函数返回一个unique_ptr。
如:unique_ptr<int> clone(int p) { return unique_ptr<int> (new int(p));
还可返回一个局部对象的拷贝:unique_ptr<int > clone(int p) { unique_ptr<int> ret (new int (p) ); return ret; }
(三)weak_ptr :伴随类,它是一种弱引用。是一种不控制所指向对象生存期的智能指针,它指向由一个shared_ptr管理的对象
1)当创建一个weak_shared时,要用一个shared_ptr来初始化它。由于是弱共享,创建wp不会改变p的引用计数;wp指向的对象可能被释放掉。由于对象可能不存在,故不能使用weak_ptr直接访问对象,而必须调用lock函数.该函数检查weak_ptr指向的对象是否存在。如:if(shared_ptr<int> np = wp.lock() ) {
... }。
2)weak_ptr作用是作为辅助,核查指针类。

(四)智能指针陷阱:
1)不能使用相同的内置指针值初始化(或reset)多个智能指针。
2)不delete get()返回的指针。
3)不使用get()初始化或reset另一个智能指针。
4)若你使用get()返回的指针,记住当最后一个对应的智能指针销毁后,该指针无效了。
5)若使用智能指针管理的资源不是new分配的内存,记住传递给它一个删除器。

十三、使用动态生存期的资源的类
1、程序不知道自己需要使用多少对象。----容器类
2、程序不知道所需对象的准确类型。
3、程序需要在多个对象间共享数据。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: