c++中const类型的使用与注意事项

1 篇文章 0 订阅
1 篇文章 0 订阅

    常量是标识符他在程序运行期间是恒定不变的,在c语言中可以用#define来定义一个常量,称为宏常量。c++中除了宏常量还可以用const来定义常量。

     常量为什么存在和存在的意义, 如果不使用常量,直接在程序中填写数字或字符串,将会有什么麻烦?

(1) 程序的可读性(可理解性)变差。程序员自己会忘记那些数字或字符串是什么意
思,用户则更加不知它们从何处来、表示什么。
(2) 在程序的很多地方输入同样的数字或字符串,难保不发生书写错误。
(3) 如果要修改数字或字符串,则会在很多地方改动,既麻烦又容易出错。

一、const修饰普通变量和指针变量

const 修饰变量有两种方式:

const TYPE value;

TYPE const value;

这两种写法本质上是相同的,对于一个非指针的类型TYPE,无论怎么写,都是一个含义,即value值不可变。

但是对于指针类型的TYPE,不同的写法会有不同情况:

 (1)指针本身是常量不可变

(char*) const p;

 (2)指针所指向的内容是常量不可变

const (char) *p;

(char) const *p;

 (3)两者都不可变

const char* const p;

识别const到底是修饰指针还是指针所指的对象,还有一个较为简便的方法,也就是沿着*号划一条线:

如果const位于*的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;

如果const位于*的右侧,const就是修饰指针本身,即指针本身是常量。

二、const修饰函数参数

用const修饰函数的参数用途非常广泛,也使程序更安全更高效。被声明为const类型的变量在函数体内不容许被改变。

int function(const int val) // val在函数体内不容许改变

int function(const char* val) //val 所指向的内容在函数体内不容许改变

int function(char* const val) // 指针变量val本身是常量 在函数体内的指向不容许改变

int function(const class &val ) // 引用类型在函数体内不许改变

经常在函数传递阐述的时候会使用引用类型是因为,如果该类型是自定的不是系统自带的基本数据类型,如果函数采取的是非引用(值传递),函数会产生临时变量并赋值该变量的至这样影响了函数调用的效率,因此在函数参数传递的过程中经常采用的是传引用。

三、const修饰类对象、对象指针、对象引用

const修饰类对象表示该对象为常量对象,其中的任何成员都不能被修改。对于对象指针和对象引用也是一样。

const修饰的对象,该对象的任何非const成员函数都不能被调用,因为任何非const成员函数会有修改成员变量的企图。

class A 

{

   public :

      int func1();

      int func2() const;

};


const A obj;

obj.func1();//error 不能调用非const函数

obj.func2();// ok


const A* obj;

obj->func1();//error

obj->func2();//ok

四、const修饰数据成员

const数据成员只在某个对象生存期内是常量,而对于整个类而言却是可变的。因为类可以创建多个对象,不同的对象其const数据成员的值可以不同。所以不能在类声明中初始化const数据成员,因为类的对象未被创建时,编译器不知道const 数据成员的值是什么,例如:
class A
{
    const int size = 100; //
错误
    int array[size];       //
错误,未知的size
}

 

const数据成员的初始化只能在类的构造函数的初始化列表中进行。

class A 

{

    A(int size);

    const int SIZE;

};

A::A(int size):SIZE(size)

{}

要想建立在整个类中都恒定的常量,可以用类中的枚举常量来实现,例如:
class A
{


  enum {size1=100, size2 = 200 };
  int array1[size1];
  int array2[size2];


}

枚举常量不会占用对象的存储空间,他们在编译时被全部求值。但是枚举常量的隐含数据类型是整数,其最大值有限,且不能表示浮点数。

五、const修饰成员函数

const修饰类的成员函数,用const修饰的成员函数不能改变对象的成员变量。一般把const写在成员函数的最后:

class A 

{

  int func() const;

};

对于const类对象/指针/引用,只能调用类的const成员函数。

六、const修饰成员函数的返回值

1、一般情况下,函数的返回值为某个对象时,如果将其声明为const时,多用于操作符的重载。通常,不建议用const修饰函数的返回值类型为某个对象或对某个对象引用的情况。原因如下:如果返回const对象,或返回const对象的引用,则返回值具有const属性,返回实例只能访问类A中的公有(保护)数据成员和const成员函数,并且不允许对其进行赋值操作,这在一般情况下很少用到。

2、如果给采用指针传递方式的函数返回值加const修饰,那么函数返回值(即指针所指的内容)不能被修改,该返回值只能被赋给加const 修饰的同类型指针:
const char * GetString(void);
如下语句将出现编译错误:
char *str=GetString();
正确的用法是:
const char *str=GetString();

3、函数返回值采用引用传递的场合不多,这种方式一般只出现在类的赙值函数中,目的是为了实现链式表达。如:
class A
{


    A &operate= (const A &other); //
赋值函数
}
A a,b,c; //a,b,c
A的对象

a=b=c;   //
正常
(a=B)=c; //
不正常,但是合法
若赋值函数的返回值加const修饰,那么该返回值的内容不允许修改,上例中a=b=c依然正确。(a=b)=c就不正确了。

还有在重载输入输出流操作符的时候也是这种情况<<, >>。

七 const常量与define宏定义的区别

l  编译器处理方式不同

define宏是在预处理阶段展开。

const常量是编译运行阶段使用。

l  类型和安全检查不同

define宏没有类型,不做任何类型检查,仅仅是展开。

const常量有具体的类型,在编译阶段会执行类型检查。

l  存储方式不同

define宏仅仅是展开,有多少地方使用,就展开多少次,不会分配内存。

const常量会在内存中分配(可以是堆中也可以是栈中)



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++ ,string 类型是一个非常常用的字符串类,可以方便地进行字符串的操作。使用 string 类型需要注意以下几点: 1. 头文件:需要包含 <string> 头文件。 2. 声明:需要使用 std 命名空间,或者在全局范围内使用 using namespace std; 声明。 3. 初始化:可以直接使用字符串字面量或者其他 string 对象初始化。 4. 操作:可以使用常规的字符串操作,如比较、拼接、查找、替换等。 5. 长度:可以使用 size() 或者 length() 方法获取字符串的长度。 6. 遍历:可以使用 for 循环或者迭代器遍历字符串的每一个字符。 7. 转换:可以使用 c_str() 方法将 string 类型转换为 const char* 类型,或者使用 stoi()、stof() 等方法将 string 类型转换为其他类型。 示例代码: ``` #include <iostream> #include <string> using namespace std; int main() { string s1 = "hello"; string s2("world"); string s3 = s1 + " " + s2; cout << s3 << endl; if (s1 == "hello") { cout << "s1 equals to hello" << endl; } int index = s3.find("world"); if (index != string::npos) { cout << "world found at index " << index << endl; } for (char c : s3) { cout << c << " "; } cout << endl; const char* cstr = s3.c_str(); cout << "cstr: " << cstr << endl; return 0; } ``` 输出结果: ``` hello world s1 equals to hello world found at index 6 h e l l o w o r l d cstr: hello world ``` 需要注意的是,string 类型的底层实现是动态分配的内存,因此在进行大量字符串操作时需要注意内存的使用。同时,由于 string 对象的复制和传递会涉及到内存的拷贝,因此也需要注意效率问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值