c++ 小知识点

记录自己遇到的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;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杨博东的博客

请我喝瓶可乐鼓励下~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值