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

  • 相关阅读:
    AGC037F Counting of Subarrays
    AGC025F Addition and Andition
    CF506C Mr. Kitayuta vs. Bamboos
    AGC032D Rotation Sort
    ARC101F Robots and Exits
    AGC032E Modulo Pairing
    CF559E Gerald and Path
    CF685C Optimal Point
    聊聊Mysql索引和redis跳表
    什么是线程安全
  • 原文地址:https://www.cnblogs.com/fydeblog/p/7103529.html
Copyright © 2011-2022 走看看