zoukankan      html  css  js  c++  java
  • 关于C++不能不知道的几件事--类、引用

    一、第一个C++程序
     1、文件扩展名
      C++源代码的文件扩展名.cpp、C、cxx、c(需要指定编译语言)
      自定义的头文件依然保留.h
     2、头文件
      C++标准库的头文件不带.h,最常用的是iostream
      C语言的头文件依然可以继续使用,stdio.h或cstdio
     3、输入输出
      cout<< 输出
      cin>> 输入
      endl 换行
      cout和cin不再使用占位符,它可以自动识别数据类型
      scanf和printf可以继续使用
    #include <iostream>
    using namespace std;
    
    int main()
    {
        int num = 100,num1;
        cin >> num >> num1;
        cout << "num = " << num << num1 << endl;
        cout << "hello world!" << endl;
        return 0;
    }
     
     4、编译器
      gcc也可以编译C++的源码,但需要添加额外的参数
      g++是编译C++源码的最简单的编译器,一般操作系统没有默认安装,ubuntu系统的安装指令:sudo apt-get install g++
      之前的gcc的编译参数,依然可以继续使用
      注意:C++编译时的错误提示不是很精准,一个错误可能产生大量的错误提示
     5、引入了名字空间概念
              using namespace std;
     
    二、C++中的基本数据类型
     1、C++完全兼容C语言中的所有数据类型(C++兼容C语言的所有语法)
     2、添加了bool类型、字节宽度1,数值true(非零值),false(零值)
     3、在显示bool变量前,使用boolalpha可以以true或发绿色的形式显示bool值
     4、void* 与其它类型指针的转换受到限制
      void* 不可以直接给其它类型的指针赋值,必须经过强制转换
      任意类型的指针都可以直接给void*赋值
      
    三、C++中的联合、枚举、结构
     1、在C++中联合、枚举、结构一旦设计成功,在之后的使用过程中不需要加关键字
     2、枚举的检查更为严格(C++中的枚举是一种独立的数据类型)
     3、结构成员中可以有函数,在函数中可以直接访问结构的成员
     4、结构对象可以继续使用.或->访问成员、成员函数
     5、结构中的成员添加了访问属性:
      public:开放的,被他修饰过的成员在任何位置都可以访问
      private:私有的,被他修饰过的成员只能在成员函数中使用
      protected:
     6、结构在创建时会自动调用一个函数-构造函数
      a、无返回值
      b、名字与结构相同
      c、参数可以是任意
     7、结构在释放时会自动调用一个函数-析构函数
      a、无返回值、参数
      b、~结构名
     
    四、引用
     1、引用就是起"外号",为一个标识符另外再取一个名字
     2、引用必须要初始化,否则编译错误
     3、引用不光可以引用标识符,也可以引用立即数(右值、字面值、常量),但必须加const属性
     4、不能定义空引用,但"野引用"或"悬空引用"是存在的(引用了堆内存的数据,当堆内存释放后就不应该再使用)
     5、引用只能是一次性,无法再更改(引用一旦成功后,它是个变量了,这个身份至死不渝)
     6、引用可以当作函数的参数,它引用的对象就是函数的实参。所以引用可以达到指针的效果
      a、函数之间共享变量
      b、提高参数的传递效率(比指针还要高)
      c、可以获取参数
      注意:能使用引用就不要再使用指针了
      引用能否完全取代指针,答案是不可以
     7、引用也可以当作函数的返回值,但绝不能返回局部变量的引用
     
    #include <iostream>
    using namespace std;
    
    void exchange(int& num1,int& num2)
    {
        int temp = num1;
        num1 = num2;
        num2 = temp;
    }
    int main()
    {
        int num1 = 10,num2 = 20;
        exchange(num1,num2);
        cout << num1 << " " << num2 << endl;
    }
     
    五、C++的内存管理运算符
     1、在C++中使用 new/delete 来管理内存,new用来申请内存,delete用来释放内存
     2、new在内存时允许对内存进行初始化
     3、使用new创建结构对象时会自动调用构造函数,delete时会自动调用析构函数
     
     总结:malloc/free 与 new/delete 的区别?
      1、malloc/free标准库的函数,使用时还需要添加头文件,而new/delete是C++语言中的运算符
      2、malloc返回的是void*指针,new返回的是有类型的指针
      3、malloc创建对象时不会调用构造函数,free时不会调用析构函数,但new/delete会自动调用构造和析构函数
      4、使用malloc申请内存时需要自己计算字节数,而使用new的时候会自动计算
      
     4、[]可以配合new和delete申请或释放数组
              new[]不可以与delete混用,必须调用delete[]释放
              使用new[]/delete[]创建多少个对象就会调用多少次构造和析构
     5、new/delete与malloc/free不能混用,可能会造成不可预知的错误
     6、delete不可以重复释放,但可以释放空指针
     7、如果使用new申请内存失败会产生抛出异常"std::bad_alloc",异常的捕获和处理会在以后讲解
     

    六、C++中的函数

     1、C++中函数可以在main前执行,C语言中不可以
     2、C++中函数名字可以相同,只要参数不同即可(函数重载,不只是参数)
      函数可以同名并不是真正意义上的同名,它只在编译基本把函数的名字添加了额外信息(函数的参数),返回值不算内
     3、内联函数
      内联函数就是把函数编译成二进制,然后在需要的位置直接把函数拷贝过去,而不是跳转后再执行,这样可以减少进栈、出栈、和调用,以此提高程序的执行效率,但这样会增加可执行文件的大小
      内联函数与宏函数的区别:从本质上来说它们是一样的,但内联函数可以检查参数,也可以具有返回值
      inline 返回值类型 函数名(参数)
      {
       
      }
     4、C++中函数的参数可以有默认值
      a、函数的默认参数要靠右
      b、默认参数要尽量少用,因为可能引起重载错误
      c、函数的默认参数是编译器在编译器帮助赋值的,所以只能由全局变量、静态变量、字面值对参数进行赋值
     

    七、名字空间

     C语言中的名字空间的划分:全局、局部、块
     C++认为:全局空间用起非常方便,但如果把太多的东西放在全局空间会造成命名冲突,所以C++引用了这样一种机制就是名字空间。
     名字空间:把全局的命名空间进一步分割,可以创建出一个个独立的命名空间防止相互之间冲突。
     1、定义名字空间:
     namespace name
     {
      变量;
      函数;
      结构、类;
     }
     2、名字空间的合并
      a、同名的名字空间会自动合并。
      b、在同一个名字空间中只标识符必须是唯一的。
     3、定义与声明分开
     namespace n1
     {
      //在名字空间中声明函数
      void func(void);
     }
     // 在名字空间外定义函数
     void n1::func(void)
     {
     
     }
     4、如何使用名字空间中的内容
      a、域限定符(::),直接使用,名字空间::标识符,这样的好处是绝对不会冲突,但就是麻烦了些。
      b、using namespace 名字空间; 功能是把名字空间中的标识符对之后的代码全部公开。
      c、using 名字空间::标识符,表示此标识符对后面的代码公开。
     
    #include <iostream>
    
    namespace n1
    {
        int cout = 15;
    }
    using std::cout;
    using std::endl;
    int num = 0;
    
    int main()
    {
        int num = 100;
        cout << ::num << endl;
        cout << n1::cout << endl;
        std::cout << "hello world!" << endl;
    }
     
     5、名字空间的嵌套
      名字空间可以嵌套,但使用时要逐层解析。
      namespace n1
      {
       int num = 10;
       namespace n2
       {
        int num = 20;
        namespace n3
        {
         int num = 30;
        }
       }
      }
      n1::n2::n3::num == 30;
      n1::n2::num == 20;
      n1::num = 10;
      using namespace n1::n2;
     6、全局空间归属为匿名空间
      在全局空间定义的标识符都属于这个匿名空间,匿名空间默认开放。
      如果函数中有同名的标识符把匿名空间中的屏蔽了,可以使用空的域限定符表示它。
     
     注意:不同命名空间中的同名函数不构成重载,同一作用域下的同名函数叫重载。
     
    #include <iostream>
    using namespace std;
    
    namespace n1
    {
        int num1 = 100;
    }
    namespace n1
    {
        int num = 200;
    }
    
    void func(void)
    {
        cout << n1::num << endl;
    }
    int main()
    {
        func();
    }


     

    八、class

     1、C++的class与struct一样,是一种复合数据类型。
     2、里面可以有变量用来表达属性,函数用来表示行为。
     3、在C++的class与struct,几乎没有任何区别。
     4、struct中默认访问属于是public,class中默认的访问属性是private。
     5、在C++默认使用class,以示与C语言中的class进行区分。
     

    九、class的构造函数

     1、在创建对象时自动调用的函数,在整个对象的生命周期中一定会被调用一次,且只能被调用一次。
     2、在构造函数中负责对成员变量的初始化、分配资源、设置对象的初始状态。
     3、构造函数可以有多个版本,这些不同的版本之间会构造重载,创建对象时的方式不同、给的参数不同会调用相应的构造函数,如果调用的构造函数不存在可能会造成编译错误。
      // 无参构造   Student stu <=> Student* stup = new Student;
      // 有参构造   Student stu(参数列表) <=> Student* stup = new Student(参数列表);
     4、如果类中没有定义构造函数,编译器会自动生成一个无参构造。
      一旦定义了其它版本的构造函数,无参构造就不会再生成了,因此为了防止无参方式创建对象出错,在定构造函数时,至少要实现两个。
     5、无参构造未必无参,在C++中函数可以有默认参数,如果有参构造全部设置了默认参数,就会和无参数构造有冲突,它们两个只能有一个存在。
     6、所谓的"编译器生成的某某函数"
      "编译器生成的某某函数",不是真正意义上的函数,编译作为指令的生成者,只要生成具有某些函数功能的指令即,没有必须生成高级语言的主义上的函数。
     7、什么时候调用无参构造
      a、Student stu <=> Student* stup = new Student;
      b、创建对象数组,每个对象都会调用一次无参构造。
      c、如果类A中有成员是类B,当执行守类A的构造函数前会自动调用类B的无参构造。
      d、在类A中如何调用类B的有参构造
      类A(参数列表):成员类B(参数列表)
      {
       ...
      }   
     8、类型转换构造函数
      用一个数据给对象初始化,默认会自动调用构造函数,达到类型转换的效果。
      这种方式虽然使用方便,但也会包容一些错误存在,如果想让代码检查更为严格可以使用explicit关键字禁止隐式转换的方式调用构造函数。
     9、也可以实现自动类型转换构造函数(默认)。
     
    #include <iostream>
    using namespace std;
    
    class Date
    {
        int year;
        int month;
        int day;
    public:
        Date(void)
        {
        }
        explicit Date(int _year,int _month=0,int _day=0)
        {
            year = _year;
            month = _month;
            day = _day;
        }
        void show(void)
        {
            cout << year << ' ' << month << ' ' << day << endl;
        }
    };
    int main()
    {
        Date* date = new Date(2018,8,7);
        date->show();
    }
  • 相关阅读:
    Java实现 蓝桥杯VIP 算法提高 交换Easy
    Java实现 蓝桥杯VIP 算法提高 多项式输出
    Java实现 蓝桥杯VIP 算法提高 多项式输出
    Java实现 蓝桥杯VIP 算法提高 多项式输出
    Java实现 蓝桥杯VIP 算法提高 多项式输出
    Java实现 蓝桥杯VIP 算法提高 多项式输出
    Java实现 蓝桥杯VIP 算法训练 矩阵乘方
    QT中给各控件增加背景图片(可缩放可旋转)的几种方法
    回调函数实现类似QT中信号机制
    std::string的Copy-on-Write:不如想象中美好(VC不使用这种方式,而使用对小字符串更友好的SSO实现)
  • 原文地址:https://www.cnblogs.com/qsz805611492/p/9451280.html
Copyright © 2011-2022 走看看