的区别 includ...">
美文网首页
C++学习随笔(四)

C++学习随笔(四)

作者: 宇宙巨炮 | 来源:发表于2020-05-06 18:09 被阅读0次

    未经本人授权,禁止转载


    这一部分会详细谈谈类


    1. include" "与include< >的区别

    include" "编译器首先查找当前工作的目录或源代码目录;
    include< >编译器首先在存储标准头文件的主机系统的文件系统中查找。

    2. 预处理器编译指令#ifndef

    以前没有预处理过include"test.h"时才执行中间的代码,可以很好的防止重复引用头文件。

    #ifndef TEST_H_
    #define  TEST_H_
    //...............
    #endif
    

    3. 类的构造函数

    直接上代码比较直观,以下面的类为例。

    class test
    {
    private:
        int num;
        string str;
    public:
        void func();
    };
    
    1. 没有构造函数编译器会隐式的声明一个默认构造函数

    test x;此时x中的num和str会被创建,但是没有任何值

    2. 自己给出构造函数时,编译器不再隐式的声明默认构造函数
    test(int t_num , const string & t_str);    //在类内部声明
    
    test::test(int t_num , const string & t_str)    //定义,构造函数没有返回值
    {
        num = t_num;
        str = t_str;
    }
    
    int main()
    {
        test x(12 , "hello world");
        test y = test(12 , "hello world");    //两种完全等价,上面的是隐式调用,下面的是显式调用
        test x;    //!!!报错!!!因为没有了默认构造函数!!!
    }
    

    自定义了构造函数但是没有自行提供默认构造函数test x;就会报错,定义默认构造函数有两种方法:

    //1. 给构造函数的所有参数提供默认值
    test::test(int t_num = 0 , const string & t_str = “err”) 
    {
        num = t_num;
        str = t_str;
    }
    
    //2. 使用函数重载来定义另一个构造函数——没有任何参数的构造函数
    test::test() 
    {
        num = 0;
        str = "null";
    }
    
    3. 在使用初始化列表初始化类对象时,只要与某个构造函数的参数列表匹配即可
    4. 构造函数的初始化列表语法
    class example
    {
    private:
        int x;
        strinh str;
    public:
        example(int _x , const string & _str);
    };
    
    example::example(int _x , const string & _str) : x(_x) , str(_str) { }    //个人觉得这样很装逼
    
    5. 在构造函数中new的变量必须在析构函数中delete
    6. 返回对象会调用复制构造函数,返回引用不会

    4. 析构函数详解

    最好是给出一个显式的析构函数,如果没有编译器将隐式的声明一个析构函数。

    class test
    {
    private:
        int num;
        string str;
    public:
        test();
        test(int t_num , const string & t_str); 
        ~test();    
        void func();
    };
    

    析构函数的调用:如果是静态存储类对象,在程序结束时自动调用;如果是自动存储类对象,在代码块{ }结束时自动调用;如果是new的对象,在delete时自动调用。最好不要主动调用析构函数!!!

    5. const成员函数

    当成员函数不修改任何成员变量时,就应该把它定义为const成员函数以保证函数不会修改调用对象。

    void func() const;
    
    void test::func() const
    {
        //...........
    }
    

    6. this指针

    this是一个指向调用对象本身的指针,*this是调用对象本身,注意二者的区别

    7. 运算符重载

    代码格式:operate运算符(),运算符必须是C++寓言已有的运算符。

    class Test
    {
    private:
        int x;
    public:
        Test(int _x = 0);
        Test operate+(const Test & t);
    };
    
    Test::Test( int _x = 0)
    {
        x = _x;
    }
    
    Test Test::operate+(const Test & t)
    {
        Test sum;
        sum.x = x + t.x;
        return Test;
    }
    
    int main()
    {
        Test a(10);
        Test b(20);
        Test c;
        c = a + b;    //等效于c = a.operate+(b);
    }
    

    运算符重载的限制:
    1.重载后的运算符必须至少有一个操作数是用户自定义的类型
    2.使用运算符不能违反原来的句法规则,不能修改运算符的优先级
    3.sizeof ,. ,.* ,:: ,?:等运算符不能重载
    4.=,(),[],->只能在成员函数中重载

    8. 友元函数

    可以获得访问类成员权限的函数。

    class Test
    {
    private:
        int x;
    public:
        friend int func();    //在类中声明
    };
    
    int func()    //定义与普通函数一样,不需要加限定符Test::
    {
        return 1;
    }
    

    func不是成员函数但是却有成员函数的权限,调用的时候也不是用成员运算符,而是和普通函数一样。

    9. 类中的static

    在类的成员变量前加上静态声明static,意味着不管创建多少类对象,他们都共同分享这个静态成员变量。

    10. 隐式复制构造函数的危害

    当构造函数中有new的变量时,最好给出显式的复制构造函数和重载一个复制运算符,因为隐式构造函数是浅复制,这会导致在析构函数被调用时容易出现问题。

    相关文章

      网友评论

          本文标题:C++学习随笔(四)

          本文链接:https://www.haomeiwen.com/subject/jmhtghtx.html