指針既可以操作指針所指向的內存地址,亦可以操作指針所指向的值;
文件打開失敗判斷:ofstream ifstream 打開失敗對象爲假,打開成功爲真
if(file)
{
}
ifstream 每次讀取都是一行;
如果以追加的方式使用fstream (ios_base::in | ios_base::app)打開文件,文件的位置是末尾,
函數入口每次都必須對傳入參數的合理性判斷;
函數在有返回值的情況下,必須在每個可能退出點上返回值;
c++ 不允許引用改變其應引用的值;從一而終;
const 引用;
指針和引用
在使用指針時必須先判斷其值非零;引用則不需要;
函數默認值建議放置在函數聲明而非定義處;
#include<limits>
numeric_limits<int>::max(); //取最大值;
inline 函數一般定義在頭文件中,inline函數一般在編譯期間就進行了展開,執行期間不存在函數調用,inline函數一般是體積小,常被調用,從事計算不復雜;
重載函數只可以是參數不一樣,不能一返回值不一樣來區分;當我們調用函數不需要返回值的時候,就沒得辦法區分
const object 一處文件其他文件便不可見;
每次使用指針的時候,需要考慮指針越界;
const_iterator
vector 和deque 都是一塊連續的內存;vector 在元素的尾端插入和刪除都是很快的;deque在容器的前後插入和刪除都很快;
#include<algorithm> //算法
find() //查找無序集合
banary_search()//查找有序集合,查詢的集合必須排序
count()//返回數值相符的元素數目
search()//從一個集合內查找子集
copy()//集合複製;必須確保目的容器有足夠容量;
函數對象; 就是重載了operator()的class
#include<funtion>
plus<type> ,minus<type>,negate<type>,mutiplise<type>,divides<type>,moudles<type>
less<type>,less_equal<type>,greater<type>,greater_equal<type>,equal_to<type>,not_equal<type>
logic_and<type>,logic_or<type>,logic_not<type>
adaptor適配器:
bind1st 綁定2元函數的第一個參數
bind2st 綁定2元函數的第二個參數;
not1是構造一個與謂詞結果相反的一元函數對象
not2是構造一個與謂詞結果相反的二元函數對象
幾元就是有幾個參數,1個參數叫1元,2個參數叫2元;
插入迭代器,使用算法函數式需要傳入一個目的迭代器,前提傳入的迭代器必須有足夠的空間,使用 iterator insertor迭代器則不需要提供足夠容量;
#include<iterator>
back_inserter()
inserter();
front_inserter(); //copy(vec.begin(),vec.end,front_inserter(dst_vex))
輸入輸出迭代器
輸入輸出迭代器
iostream iterator
vector<string> vec;
istream_iterator<string> in(cin);
istream_iterator<string> eof;
copy(in,eof,back_inserter(vec);
ostream_iterator<string> out;
copy(vec.begin(),vec.end(),out);
class 內部定義的函數一般會認爲是inline函數;
每個類是否需要拷貝構造函數和賦值函數;
如果類中存在const成員函數,那就必須在聲明和實現中都指定const;
如何給類定義一個迭代器:
class Test_iterator
{
private:
list<int>::iterator it;
//T x;
//list<int>::iterator i;
public:
Test_iterator(list<int>::iterator i):it(i)
{
}
Test_iterator& operator++()//前置++
{
it++;
return *this;
}
Test_iterator& operator++(int)//後置++
{
it++;
return *this;
}
Test_iterator& operator--()
{
it++;
return *this;
}
int & operator*()
{
return *it;
}
bool operator==(const Test_iterator &a)
{
return it == (a.it);
}
bool operator!=(const Test_iterator &a)
{
return it != (a.it);
}
};
class Test
{
private:
mutable int x;
list<int> li;
//const int x;
public:
typedef Test_iterator itrator;
void set_x(int a) const;
void push_back(int a)
{
li.push_back(a);
}
list<int>::iterator begin()
{
return li.begin();
}
list<int>::iterator end()
{
return li.end();
}
};
int mian()
{
Test t;
t.set_x(3);
t.push_back(1);
t.push_back(2);
t.push_back(3);
t.push_back(4);
Test::itrator it(t.begin());
for (auto it = t.begin(); it != t.end(); it++)
{
cout << *it << endl;
}
}
靜態綁定:編譯時確定調用的實例
動態綁定:執行期間才知道調用的實例;
靜態函數不可以聲明爲虛函數;
含有儲純虛函數的類不可以定義實例變量,必須有子類派生,並且子類實現其虛函數,纔可以定義實例對象;
抽象基類的析構函數一定要定義爲虛函數,主要是放置內訓泄露;
{
//這種情況就會出問題
parent *p = new child()
delete p;
}
在類外定義虛函數時不需要指定virtual
當基類的虛函數返回每個基類的形式(通常是引用或者時指針),派生類的重載同名函數就可以返回派生類的形式,這種形式不影響多態調用;
class base{
virtual base & copy()
{
cout << "child copy" << endl;
return *this;
}
}
class child:public base{
virtual child & copy()
{
cout << "child copy" << endl;
return *this;
}
}
基類的構造函數內部不要調用虛函數,因爲子類的數據成員還未定義,可能會發生未定義行爲;
RTT
typeid(*this).name() //返回類名稱;#include<typeinfo> typeid 返回一個type_info對象;
支持 == 比較 if(typeid(*this) ==typeid(child)){ }
異常的一網打盡的方法(3個點) try{}catch(...){}
C++ 規定異常必須處理,否則程序調用reiminate()結束進程;