zoukankan      html  css  js  c++  java
  • C++学习笔记——大杂烩

    C++学习笔记——大杂烩

                                                            by方阳

    版权声明:本文为博主原创文章,转载请指明转载地址

    http://www.cnblogs.com/fydeblog/p/7103529.html 

    摘要:这篇博客主要记录学习C++11的一些好方法!博客最后有这个笔记的百度云链接!

    1.  命名空间

    使用命名空间,最好是分别引入,需要用哪个引用哪个,保证程序中名称的唯一性,避免全局污染(即自己定义与全局空间冲突)

    For example:

    Using std::cout 或直接编程用std::cout(好) using namespace std(不好)

    2.  空指针

    C++11中使用字面值nullptr初始化指针来得到空指针。

    注意:使用未经初始化的指针是引发运行错误的一大原因。

    Best practices :先定义对象,然后再去定义指向的指针。

    3.  const与constexpr

    顶层const:表示指针本身是一个常量

    For example

    1. int *const p1 = &i ;  //不能改变p1的值(其中i前面已经初始化)
    2. const int ci = 42 ;   //不能改变ci的值

    底层const:表示所指的对象是一个常量

    For example

    1. const int *p2 = &ci; //允许改变p2的值,const int *p2应用很普遍,需要掌握
    2. const int &r = ci;

    constexpr:便于编译器检验变量的值是否是一个常量表达式

    1. 声明为constexpr的变量一定是一个常量,而且必须用常量初始化表示

    Best practices:如果认定变量为一个常量表达式,则申明为constexpr类型

    4.auto和decltype

    auto是让编译器通过初始值来推算变量的类型

    decltype是从表达式的类型来推断要定义的变量类型

    具体参考一下博客,写得非常好

    http://towriting.com/blog/2013/08/08/improved-type-inference-in-cpp11/

    这里注意一点,decltype双层括号永远是引用,而单层只有表达式本身是引用才是引用。

    5.头文件

    头文件最好是要进行预处理,就是#ifndef和#define,能有效地防止重复包含的发生

    头文件不应包含using申明

    6.string

    基本操作;

    cout<<s   //将s写到输出流os当中,返回os

    cin>>s    //从is中读取字符串赋给s,字符串以空格分割,返回is

    getline(cin,s) //从cin中读取一行赋给s

    s.empty()  //s为空则返回true,否则返回false

    s.size()    //返回字符的个数

    s[n]      //返回引用s中的第n个字符

    如果想知道某个字符的特性,使用cctype头文件中的函数

    7.范围for

    C++11提供了一种基于范围for的语句(见C++primer的83面)

    for example

    for(declaration: expression)

    statement

    其中expression表示一个对象,用于表示序列;declaration负责定义一个变量,会被依次初始化expression部分的下一个元素值。

    8.vector

    常见的初始化vector对象的方法

    Vector<T> v1

    Vector<T> v2 ={a,b,c..} //其中T为类型名,可以为int,double,sales_item(类)

    Vector<T> v3 =(n,val) //v3包含了n个重复的元素,每个元素的值都是val

    Vector支持的操作

    v.empty()      //v不含任何元素,返回true,否则返回false

    v.size()        //返回v中元素的个数

    v.push_back(t)  //v的尾部添加一个值为t的元素

    v[n]          //返回v中第n个位置上元素的引用

    迭代器的使用(重要)(可以用迭代器的有很多种,如string、vector、list等等)

    v.begin() //返回指向容器的第一个元素

    v.end()  //返回指向容器的尾元素的下一位置

    for example(来自libviso2中的match.cpp)

    for (vector<p_match>::iterator it=p_matched_2.begin(); it!=p_matched_2.end(); it++)

    当然上面的可以进行简化

    for (auto it=p_matched_2.begin(); it!=p_matched_2.end(); it++)

    还是拿上面的例子来介绍箭头运算符

    首先it为指向地址,所以要引用*it的成员函数或成员变量,需要使用(*it).uv1,(*it).empty

    注意:上面的括号不能去掉,去掉就是访问it的成员了,而it是一个迭代器,没有empty和uv1成员,所以不能去掉

    C++定义了箭头运算符(->),将解引用和成员访问结合在一起(建议用箭头运算符)

    所以  (*it).empty与it->empty() 等价

    (*it).uv1   与it->uv1    等价

    9.switch语句要点

    1. 必须在必要的地方使用,通常是每一case都要在末尾加break

    2. 应该把变量定义在块作用域内(即申明变量可以在switch外)

    3. case标签只能有一个,且必须是常量

    10.this用法

    这里介绍一种常见用法

    For example

    Sales_data& Sales_data::combine(const Sales_data &rhs)

    {

       uints_sold+=rhs.uints_sold;      //把rhs的成员加到this对象的成员中

       revenue+=rhs_revenue;        //把rhs的成员加到this对象的成员中

       return *this                  //左值返回调用该函数的对象

    }

    这是C++ primer中的一个例子,这个函数返回的是Sales_data的引用,函数的形参也是Sales_data的引用,比如说,定义了Sales_data的两个对象:total和trans

    那么可以这样使用上面的函数,total.combine(trans);

    调用这个函数时,会将total的地址绑定在隐式的this参数上,this就具有了total的所有属性,而rhs绑定到了trans上,因此函数的第一行和第二行的uints_sold和revenue其实是this->uints_sold和this->revenue,只不过隐式可以省略,返回*this就更新了total对象

    11. 构造函数和析构函数

    在申明一个类的时候,我们可能会用到它的构造函数和析构函数,构造函数是在申明类的对象时进行的一个初始化函数,一般的,我们会在构造函数中初始化一些该类的参数,而析构函数则是在类的对象结束后运行的函数,一般会在析构里释放一些中间变量的内存。

    具体可以参考libviso2的match.cpp的构造和析构函数。

    下面额外介绍一个关于构造函数的知识点

    比如说,构造了一个TEST类,它有成员变量a,b,c还有一个构造函数

    它的构造函数是这样

    TEST(int x, int y):a(x),b(y),c(0){}

    这是用括号内的值,来初始化成员变量值。与函数内部赋值相比,初始化列表的方式更高效。Libviso2中的match部分的参数也是由这种方式初始化的。

    12.IO库

    这里只介绍一些实用的,详细地请参考各类书籍

    我们常见的IO对象有cin,cout,cerr

    Cin和cout不用多介绍了,这里说一下cerr,这个通常用于输出程序的错误信息,挺有用的,使用的方法与cout一样

    cerr << "ERROR: Couldn't read input files!" << endl;

    再来说说文件输入输出,它的文件是fstream,有两种常用的类,ifstream和ofstream,前者对应从文件读数据,后者是从文件写入数据,一般使用它的成员函数open(file)和close()来控制文件的打开和关闭。

    For example(写数据)

    ofstream file;

    file.open("file.txt");                   
    file<<"Hello file/n"<<75;                         
    file.close();                                                      

    For example(读数据)

    ifstream file;

    char output[100];

    file.open("file.txt");

    file>>output;               

    file.close();

    13.int main (int argc, char* argv[])

    其中argc代表:输入的参数个数    

    其中argv代表:此可执行文件的存储路径、输入程序变量

    int   main(int   argc,   char*   argv[])  
       {  
       for  (int i   =   0;   i<argc;   i++)  
       cout<<argv[i]<<endl; 
       return   0;  
       }  
       执行时敲入  
       D:C++project est1debug est.EXE   aaaa   bbbb   cc   dd
       输出如下:  
       D:C++project est1debug est.EXE  
       aaaa  
       bbbb  
       cc 
       dd

    14.const在函数的使用

    1.在函数形参里的使用

    for example

    cv::Mat Converter::toCvMat(const Eigen::Matrix<double,4,4> &m)

    这个函数形参是 Eigen4X4矩阵的引用,它是const型,也就是只能读,不能写

    2.在函数返回类型加const

    这个故名思议,返回的类型必须是只读,不能进行修改

    3.是在函数后面加const

    for example

    int  FunctionConst::getValue2()  const

    这个意思是不能修改类的成员,注意,这里的类是指FunctionConst,这个类的成员不能修改

    best practices: 多使用const,可提高程序的可读性,还能提高程序的可靠性,已定义成const的成员函数,一旦企图修改数据成员的值,则编译器按错误处理。

     

    文档百度云链接:http://pan.baidu.com/s/1qYNSfqW 密码:n1p3

  • 相关阅读:
    HDU4385Moving Bricks【状压DP】
    用位运算实现加减法
    hdu 1874(最短路 Dilkstra +优先队列优化+spfa)
    codeforces 782B The Meeting Place Cannot Be Changed+hdu 4355+hdu 2438 (三分)
    hdu 1542(线段树+扫描线 求矩形相交面积)
    hdu 2602(经典01背包)
    hdu 1698(线段树区间更新)
    hdu 1754(单点更新 ,区间最大值)
    NYOJ 寻找最大数
    hdu 2222(AC自动机模版题)
  • 原文地址:https://www.cnblogs.com/fydeblog/p/7103529.html
Copyright © 2011-2022 走看看