zoukankan      html  css  js  c++  java
  • 常量const

    const类型是你对编译器承诺的一个常量,仅仅是承诺,你可以像现实生活中一样打破承诺。但是就像现实生活中一样,我们也应该遵守承诺。常量类型的作用就是使代码变得更加简洁高效。

    如果我们新建一个整型变量,那么我们是可以随意修改他的

    int a=5;
    a=2;

    但是如果变成常量的话则无法去修改

    const int Max_Nun=90;
    Max_Num=12;//行不通的

    意思就是"我声明了一个变量,并且我永远不会去改变它的值。"

    另一个const常量的使用方式就是指针。

    #include<iostream>
    #include<string>
    
    int main()
    {
        const int MAX_NUM = 100;
        int *a = new int;
        a = &MAX_NUM;
        std::cout << *a << std::endl;
        std::cin.get();
    }

    这样写的话会出错,需要进行强制类型转化

    #include<iostream>
    #include<string>
    
    int main()
    {
        const int MAX_NUM = 100;
        int *a = new int;
        a = (int*)&MAX_NUM;
        std::cout << *a << std::endl;
        std::cin.get();
    }

    将整个常量地址传给一个普通的整型变量,这就是"打破承诺"的一种方法

    新建一个“常量指针”,同样发现是不可以修改的

    #include<iostream>
    #include<string>
    
    int main()
    {
        const int MAX_NUM = 100;
        const int *a = new int;
        a = 5;//无法运行
        std::cout << *a << std::endl;
        std::cin.get();
    }

    对于const int * 来说,不能更改指针指向的值,但是可以让别的指针指向它,下面两种写法是一样的意思

    const int *a=new int;
    int const *a=new int;

    对于int* const  来说,可以对指针指向的值进行修改,但是不能让它指向其他的地方

    #include<iostream>
    #include<string>
    
    int main()
    {
        const int MAX_NUM = 100;
        const int *a = new int;
        int* const b = new int;
        *b = 2;
        b = (int*)&MAX_NUM;//error
        std::cout << *a << std::endl;
        std::cin.get();
    }

    如果写成这样:const int* const  那么既不可以修改指针指向的值,也不可以指向别的地址。

    const在类和方法中的应用,这个const的作用就是禁止修改成员变量

    #include<iostream>
    #include<string>
    
    class Entity
    {
    private:
        int m_X, m_Y;
    public:
        int Get_X() const
        {
            m_X = 1;//error
            return m_X;
        }
    };
    int main()
    {
        const int MAX_NUM = 100;
        const int *a = new int;
        int* const b = new int;
        *b = 2;
        b = (int*)&MAX_NUM;//error
        std::cout << *a << std::endl;
        std::cin.get();
    }
    const int* const Get_X() const
    {}

    第一个const的意思是常量指针不可修改,第二个是无法指向其他地址,第三个是函数Get_X无法修改类的成员变量

    现在给出这样一个类,他的返回x函数是const型,意味着它不会修改类的成员,我们在主函数中声明该类的一个实体,通过函数将他打印出来

    #include<iostream>
    #include<string>
    
    class Entity
    {
    private:
        int m_X, m_Y;
    public:
        int Get_X() const
        {
            return m_X;
        }
    };
    
    void PrintEntity(Entity e)
    {
        std::cout << e.Get_X << std::endl;
    }
    int main()
    {
        Entity e;
       PrintEntity(e); std::cin.
    get(); }

    函数PrintEntity的传入值是Entity e,是主函数中实体类的复制,但是如果我不想使用复制,我想使用引用来直接调用这个实体类

    如果传入值是const Entity *e,那么e可以指向别的地址,但是e中存的值不能修改

    void PrintEntity(const Entity *e)
    {
        e = NULL;
    }

    如果传入值是引用,const Entity &e

    void PrintEntity(const Entity &e)
    {
        e = Entity();//error
    }

    但是如果我们将类中Get_X()后面的const删掉,会发现PrintEntity函数会报错

     以为这个Get_X函数不能保证他不修改类中的成员变量,如果Get_X是这样的

    class Entity
    {
    private:
        int m_X, m_Y;
    public:
        int Get_X()
        {
            m_X = 2;
            return m_X;
        }
    };

    那么就会修改类中的成员变量,跟函数传入的常量类型引用冲突,改正方法是在Get_X()后面加上const,或者将PrintEntity函数的传入值去掉const,如下图

     如果我们在类中写两个Get_X()函数,一个后面有const,一个没有

    #include<iostream>
    #include<string>
    
    class Entity
    {
    private:
        int m_X, m_Y;
    public:
        int Get_X()const
        {
            return m_X;
        }
        int Get_X()
        {
            return m_X;
        }
    };
    
    void PrintEntity(const Entity &e)
    {
        std::cout << e.Get_X() << std::endl;
    }
    int main()
    {
        Entity e;
        std::cin.get();
    }

    那么可以看到类调用的是后面有const的方法

    这样会显得很麻烦,所以要记住,当类中的函数确定不改变成员变量时,要在它的后面加上const

    但是如果我就是想在后面有const的方法中改变成员变量,那么可以使用mutable,用mutable声明过的可以修改

    class Entity
    {
    private:
        int m_X, m_Y;
        mutable int var;
    public:
        int Get_X()const
        {
            var = 3;
            return m_X;
        }
        int Get_X()
        {
            return m_X;
        }
    };
  • 相关阅读:
    JVM中java类的加载时机(转载:http://blog.csdn.net/chenleixing/article/details/47099725)
    自定义filter包
    Tomcat中Listener的使用范例(转载http://cywhoyi.iteye.com/blog/2075848)
    Quartz简单使用
    PAT A1119 Pre- and Post-order Traversals [前序后序求中序]
    PAT A1115 Counting Nodes in a BST [二叉搜索树]
    PAT A1110 Complete Binary Tree [完全二叉树]
    PAT A1102 Invert a Binary Tree [反转二叉树]
    PAT A1099 Build A Binary Search Tree [二叉搜索树]
    PAT A1094 The Largest Generation [树的遍历]
  • 原文地址:https://www.cnblogs.com/wangtianning1223/p/12726951.html
Copyright © 2011-2022 走看看