C++中const用法

const的用法文字说明都来自《C++编程思想》,这本书买了很久,一直都没有看。因为太厚,把它当工具书还行。一些代码只是随意写的,记录一下,留个脚印

要使用const 而非#define。用const来代替#define
#define把定义放到头文件中,我们同样也可以把const放到头文件中。
const定义必须给初值,除非用extern做声明的。
看下列代码:
这里写图片描述
我没有给初值,就报错了。
用extern const int i; 就不会报错 因为extern关键字说明它是一个外部的变量。这里只是声明。

现在把const int i= 100; 放到一个单独的文件中Test1.h
在main.cpp文件中
这里写图片描述
如果没有包含头文件,就会提示错误
现在把头文件包含上就正确了。
现在在Test1.h中把const int i=100; 改成 extern const int i=100;

这个时候就会报多重定义的错误。
Const 默认是内部连接的,所以不能再一个文件中定义const 在另一个文件中用extern 来引用。为了使用const成为外部连接以便让另外一个文件可以对他引用,必须明确的把他定义成extern。

这个时候我在main.cpp文件中需要引用i,则不能包含头文件,可以用。
extern const int i;
这里写图片描述

指向const的指针
定义一个指针的技巧是在标识符的开始处读它并从里向外读。Const 修饰 “最靠近”它的那个。
const int * p; 从标识符开始,是这样读:u是一个指针,它指向一个const int。这个时候它并不是一个const 变量,所以可以不初始化也不会出问题。
这里写图片描述
编译没有错误。

如果想要指针本身不变,很多人想当然的这样定义。
int const * p;
错误读法: p是一个指向int 的const 指针
正确读法:p是一个指向恰好是cont的int的普通指针。 (摘自《C++编程思想》)
这个和上面的const int * p;是同一个意思,这个容易混淆

使指针本身成为一个const指针,必须把const表明的部分放在*的右边
int d =1;
int * const w = &d;
w是一个指针,这个指针是指向int的const指针。
因为指针本身现在是const指针,编译器要求给他一个初值。
这里写图片描述
这个和之前定义const 变量没有给初值报同样错误。

const int * const x = &d; 指针和对象都不能改变

赋值和类型检查
可以把一个非const对象的地址赋值给const指针,但是不能把一个const对象地址赋值给一个非const指针。

函数参数和返回值
void f(const T t) ;
const 的含义是t不能被在函数里面修改。如果T是值传递就没多大意义,因为此时会生成一个副本。
void f(const T & t); 这个时候就能充分体现用处了。T不能被修改。

const int g(); 此时和上面类似,如果返回的是一个值类型,感觉意义不大,但是如果在类中,返回的是成员变量之类的。那就比较有意义。

如果一个函数按值返回一个类对象为const时,那么这个函数的返回值不能是左值。因为是const 所以不能修改。
如果返回的是指针或者引用,调用者就可以获得这个指针和应用来改变对象,如果不想调用者来改变你的对象,可以在前面加上const。这样就组织调用者修改。

const 用于class的两种方法

在类中定义const变量

class IntArray
{
public:
    IntArray(int size);
    virtual ~IntArray();
public:
    void setValue(int index,int value);
    int getValue(int index) const;
    void printfAll()const;
private:
    const int arraySize;
int* array;
private:
    IntArray(const IntArray & arr);
    IntArray &operator=(const IntArray & arr);
};
#include <iostream>


IntArray::IntArray(int size):arraySize(size)
{
    array = new int[arraySize];
}

IntArray::~IntArray()
{
    delete [] array;
}

void IntArray::setValue(int index, int value)
{
    array[index] = value;
}

int IntArray::getValue(int index) const
{
    return array[index];
}

void IntArray::printfAll() const
{
    for(int i=0;i<arraySize;i++)
    {
        std::cout<<i<<"  "<<getValue(i)<<std::endl;
    }
}

const成员变量只能在构造函数初始化列表中初始化。
在函数后面加入const 证明此函数并没有改变成员变量的数据,可以在const对象中使用。
如果想要在一个const函数中类的成员被修改,可以在成员变量前面加mutable关键字。

class B
{
public:
    B();
    ~B();
public:
    int getIValuePlus() const;
    int getJValuePlus() const;
private:
 mutable int i;
    int j;

};
B::B()
{

}

B::~B()
{

}

int B::getIValuePlus() const
{
    i++;
    return i;
}

int B::getJValuePlus() const
{
    j++;
    return j;
}

这个时候会报错。
这里写图片描述
但是改变i的值不会报错。

猜你喜欢

转载自blog.csdn.net/zpbrook/article/details/45670789