关于const的一些知识点小结

来源:互联网 发布:论文代发机构 知乎 编辑:程序博客网 时间:2024/06/04 18:07

参考《effectiveC++》条款1,条款21和29

在C++中用一个const变量来代替#define能够增加可读性,并且有利于编译出错时错误的定位。

const变量需要在定义时就初始化,因此类的某个成员变量为const时,在构造函数中需要用初始化式而不能用赋值的方式给它初始化(因而构造函数中采用初始化式具有更好的性能)。

const typename* p 表示的是一个指向常量的指针,所指的内容不能修改(const在*前)。

typename* const p 表示的是指针本身是一个常量,指针的值不能被修改,意思是只能指向同一个地址(const在*后)。

在全局作用域声明的const对象是定义该对象的文件的局部变量,如果要在其他文件中访问const对象,需要指定该对象为extern。

//file1.cc

extern const int bufsize = 1200;//对于非const变量只需要在声明处加上extern即可

//file2.cc

extern const int bufsize;

for(int i = 0; i != bufsize;i++)

//..........

如果对于一个类,它的成员函数需要返回的是它的一些私有成员,为了使这个类的对象的const属性与返回值的const属性一样,需要重载该函数的两个版本。例如:

class string

{

private:

char *data;

public:

operator  char *() ;

        operator  const char* () const;

string(const char *value);

        ~string();

}

对于string类来说,char*()定义了它到char×的一个强制类型转换。对于string的const对象con_object,我们也希望通过这个强制类型转换获得它对应的那个字符数组,假设为a,那么a与data指向的是同一地址空间。但是如果返回的不是一个const类型的char×,那么我们就可以通过改变a所指向的值,这与我们的期望不符。我们可以重载一个返回值为const char×类型的函数来与const对象相匹配。

上面这种情况只是针对类的成员函数需要返回某些成员(不修改成员)时,针对类的const的对象作出的相应的修改。

但是有时候我们需要对const的对象里面的某些成员作出修改该如何解决呢。

例如:

class string

{

private:

char *data;

size len;

        bool is_len_valid;

public:

operator  char *() ;

        operator  const char* () const;

string(const char *value);

        ~string();

size_t get_len() const;

}

对于const对象我们仍然需要获得字符串的长度,因此get_len()函数声明为const,它的函数主体如下:

size_t string::get_len() const

{

len = strlen(data);

is_len_valid = true;

return len;
}

但是上述的程序编译就会报错,原因就在于我们修改类的成员len和is_len_valid的值。上述问题的解决办法由两个:一是将len和is_len_valid的类型加上关键字mutable。但是一些老的编译器可能不支持。还有一种方法,是在函数内部初始化一个局部变量指针(非const的),让其也指向this所指的对象,通过修改这个局部变量所值的值来间接完成,如下:
size_t string::length() const

{

string * const local_this = const_cast<string* const>(this);

local_this->len = strlen(local_this->data);

local_this->is_len_valid = true;

return len;
}


0 0
原创粉丝点击