记录自己遇到的c++小知识点,不断更新中……
2016.03.13
1:数组间拷贝只能使用for循环一个一个拷贝,但是vector之间可以直接用一个vector初始化另一个vector。
int main()
{
// array
int arr[10];
for (int i = 0; i < 10; ++i) arr[i] = i;
int arr2[10];
for (int i = 0; i < 10; ++i) arr2[i] = arr[i];
// vector
vector<int> v(10);
for (int i = 0; i != 10; ++i) v[i] = arr[i];
vector<int> v2(v);
for (auto i : v2) cout << i << " ";
cout << endl;
return 0;
}
2:vector 之间比较大小直接用==
.
3:对于实参类型相同,并且数目不确定的情况下我们可以传递名为initializer_list的标准库类型。
int func(std::initializer_list<int> il)
{
int a;
for(auto it = il.begin();it != il.end();++it) {
a += *it;
}
return a;
}
int main(int argc,char *argv[])
{
cout << func({1,2,3,4}) << endl;
return 0;
}
4:不要将局部变量的引用传递回来,因为函数结束,局部变量被销毁,传回来的引用会失效。
int& func()
{
int i = 4;
return i;
}
int main(int argc,char *argv[])
{
int &i = func();
cout << i << endl;
return 0;
}
5:内联函数:声明在类中间的没有特殊说明的都是内联函数,我们也可以在类的内部或者内外用inline显式声明内联函数 。
6:有元:不仅可以声明某个类之间有元,还可以声明别的类中某个成员函数与类有元。
7:委托构造函数:总有一个非委托构造函数在前面,非委托构造函数一般全部变量都会声明上。
//5,6,7的例子看下面
#include<iostream>
#include<string>
#include<vector>
using std::cin;
using std::cout;
using std::endl;
class Screen;
class Window_mgr {
using ScreenIndex = std::vector<Screen>::size_type; //ScreenIndex是一个不超过vector大小的数字
public:
void clear(ScreenIndex);
private:
std::vector<Screen> screens;
};
class Screen {
using pos = std::string::size_type;
friend class Window_mgr; //Window_mgr下的成员函数全部可以访问Screen
friend void Window_mgr::clear(ScreenIndex); //Window_mgr下的clear可以访问此Screen中的数字
public:
Screen() = default;
Screen(pos ht,pos wd,char c):height(ht),width(wd),contents(ht*wd,c){ }
Screen(pos ht,pos wd):height(ht),width(wd),contents(ht*wd,' '){ }
char get() const { return contents[cursor]; } //隐式内联
inline char get(pos r,pos c); //显式内联
Screen& move(pos r,pos c); //显示外联
Screen& set(char);
Screen& set(pos,pos,char);
Screen& display(std::ostream &os) { os << contents; }
private:
pos cursor = 0;
pos height = 0;
pos width = 0;
std::string contents;
};
void Window_mgr::clear(ScreenIndex i) //将第i个屏幕清除
{
Screen &s = screens[i];
s.contents = std::string(s.height*s.width,' ');
}
Screen& Screen::set(char c)
{
contents[cursor] = c;
return *this;
}
Screen& Screen::set(pos r,pos c,char x)
{
contents[r*width+c] = x;
return *this;
}
char Screen::get(pos r,pos c)
{
pos row = r*width;
return contents[row+c];
}
inline Screen& Screen::move(pos r,pos c)
{
pos row = r*width;
cursor = row + c;
return *this;
}
int main(int argc,char *argv[])
{
Screen screen(3,4,'a');
screen.set(0,3,'A');
screen.display(cout);
return 0;
}
8:注意声明无参数的类时不要和声明函数混淆
Screen s(); //实际上声明的是一个函数
Screen s; //声明一个无参数的类,调用默认的无参构造函数
9:try-catch子句
#include<iostream>
#include<stdexcept>
#include<exception>
using std::cin;
using std::cout;
using std::endl;
int main(int argc,char *argv[])
{
int a,b;
while(cin >> a >> b) {
try {
if(b == 0) { //如果除数为0
throw std::runtime_error("divisor is 0\n");
}
cout << a/b << endl;
break;
} catch (std::runtime_error err){ //捕获异常
cout << err.what();
}
}
return 0;
}
10:explicit:显式构造函数
只针对一个实参的构造函数
11:istringstream
:我们会这样保存类的数据,假设类数据域有ID,姓名,成绩,我们可以在文件中将一个类的信息保存成一行,然后我们需要处理的时候可以每次读出一行,然后用istringstream
将读出的行按照空格处理。下面的程序就是一个例子:
#include<iostream>
#include<string>
#include<fstream>
#include<sstream>
using std::cin;
using std::cout;
using std::endl;
struct Sales_data {
Sales_data() = default;
Sales_data(std::string b,unsigned u,double r):bookNo(b),units_sold(u),revenue(r){ }
std::string isbn() const { return bookNo; }
Sales_data& combine(Sales_data &sales);
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0;
};
Sales_data& Sales_data::combine(Sales_data &sales) {
units_sold += sales.units_sold;
revenue += sales.revenue;
return *this;
}
int main(int argc,char *argv[])
{
std::string line;
std::ifstream ifs(argv[1]); //argv[1]是读入文件
std::ofstream ofs(argv[2],std::ios_base::app); //argv[2]是处理后写入的文件
if(std::getline(ifs,line)) {
std::istringstream word(line); //下面的方式也可以初始化word
//word >> line;
Sales_data total;
word >> total.bookNo >> total.units_sold >> total.revenue; //word会自动分开line的内容然后初始化total
while(std::getline(ifs,line)) {
std::istringstream word;
word >> line;
Sales_data trans;
word >> trans.bookNo >> trans.units_sold >> trans.revenue;
if(total.isbn() == trans.isbn()) {
total.combine(trans);
}else {
//最后将合并后的total的信息写入文件
ofs << total.bookNo << " " << total.units_sold << " " << total.revenue << endl;
total = trans;
}
}
ofs << total.bookNo << " " << total.units_sold << " " << total.revenue << endl;
}
return 0;
}