从零开始的C++那些事儿(零)

从零开始的C++那些事儿(零),第1张

从零开始的C++那些事儿(零)

从零开始的C++那些事儿(零)
  • 项目介绍
    • const那些事
      • const的含义
      • const作用
      • const对象的访问范围
      • const与指针
      • const在函数中的使用
      • const在类中的使用

项目介绍

这是笔者自己阅读C++那些事的过程中的笔记整理。该项目是一个适合初学者从入门到进阶的C++仓库。这里笔者和大家分享自己的阅读过程。希望大家在C++的学习过程中能够找到自己的乐趣。

const那些事

主要介绍类型修饰符const在C++中的各种使用方式,和使用过程中需要注意的要点。

const的含义

常类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不可更新的。

const作用
  • 定义常量,如const int n = 100;定义常量时必须进行初始化,同时常量在定义之后不可更改!
  • 类型检查, const常量具有类型,编译器可以进行安全检查,这也是#define宏定义常量无法做到的
  • 可以防止修改,如void func(const int n){ n++; //error }
  • 可以减少内存消耗,节省空间,避免不必要的内存分配,const定义常量从汇编角度来看,只给出对对应的内存地址,所以const定义的常量在程序运行过程中只有一份拷贝。
const对象的访问范围

const对象默认为文件局部变量,非const变量默认为extern。要使const变量能够在其他文件中访问,必须在文件中显式地指定为extern。

//file1.cpp
int ext;
//extern_file.cpp
extern const int EXT = 10;
//file2.cpp
#include 
extern int ext;
extern const int EXT;
int main()
{
	std::cout << ext << std::endl; //0
	std::cout << EXT << std::endl; //10
}
const与指针

const和指针同时使用时,用如下四种方式:

const char * a; //指向const对象的指针即指向常量的指针
char const * a; //同上
char * const a;	//指向类型对象的const指针。或者说常指针、const指针
const char * const a;//指向常量的常指针

小结:如果const位于*左侧,则const就是用来修饰指针指向的变量,即指针指向为常量,指针指向的内容不可更改;如果const位于*右侧,const就是修饰该指针本身,指针指向的地址不可更改,但是内容可以更改。

具体使用:
(1) 指向常量的指针

const int *ptr;
*ptr = 10; //error
const int p = 10;
ptr = &p; //ok
int* ptr2 = &p; //error

但是需要注意的一点是:允许把非const对象的地址赋值给指向const对象的指针

const int *ptr;
int val = 3;
ptr = &val; //ok
*ptr = 4; //error
val = 5; //ok

我们不能通过ptr修改val的值,但是可以通过其他方式修改val的值,同时ptr中的内容改变。
(2) 常指针
const指针必须进行初始化,且const指针指向的地址不能修改,但内容可以修改。

#include
using namespace std;
int main() {

    int num = 0;
    int* const ptr = #
    int* t = #
    *t = 1;
    cout << *ptr << endl; //1
    *ptr = 2;
    cout << *ptr << endl; //2
    int num1 = 10;
    ptr = &num1; //error
}

(3) 指向常量的常指针
上面两种方式的结合:

	const int a = 1;
	const int b = 2;
	const int* const ptr = &a;
	*ptr = 3; //error
	ptr = &b; //error

既不可以更改内容,又不可以更改指向地址。

const在函数中的使用
  1. const修饰函数返回值
    (1) const int 本身无意义,参数需要返回本身赋值给其他变量。
const int func1();

(2) const int* 指针指向的内容不可更改。

const int* func2();

(3)int *const 指针本身不可更改

int *const func3();
  1. const修饰函数参数
void func(const int var); // 传递过来的参数不可变
void func(int *const var); // 指针本身不可变

参数在函数内部不可更改,无意义。

void StringCopy(char *dst, const char *src);

参数指向的内容不可更改,防止在函数内部对src的更改,当函数体内的语句试图改动src的内容是,编译器将指出错误。

void func(const A &a)

比较常用的方式,参数为引用,在增加效率的同时,防止了函数体内部对参数的修改。

void func(A a) 和 void func(A& a)的区别:
void func(A a)会在函数体内部生成A类型的临时对象用来复制参数a,而临时对象的构造、复制、析构过程都将消耗时间。
void func(A &a)提高效率,“引用传递”仅借用一下参数的别名而已,不需要产生临时对象。
在此基础上,使用const修饰符,即可防止函数体内部对参数的修改。

const在类中的使用

在一个类中,任何不会修改数据成员的函数都应该声明为const类型。如果在编写const成员函数时,不慎修改
数据成员,或者调用了其它非const成员函数,编译器将指出错误,这无疑会提高程序的健壮性。使用const关
字进行说明的成员函数,称为常成员函数。只有常成员函数才有资格 *** 作常量或常对象,没有使用const关键字
明的成员函数不能用来 *** 作常对象。

  1. 类中的const成员变量必须通过初始化列表进行初始化。
//Object.h
class Object
{
public:
	Object(int i);
	const int num;
};

//Object.cpp
#include "Object.h"


Object::Object(int i) : num(i)
{
}

  1. const对象只能访问const成员函数,而非const对象可以访问任意的成员函数,包括const成员函数。
//Object.h
class Object
{
public:
	Object(int i);
	const int num;

	void doSomeThing();
	void doSomeThingConst() const;
};

//Object.cpp
#include "Object.h"
#include 

Object::Object(int i) : num(i)
{
}

void Object::doSomeThing()
{
	std::cout << "do " << num << std::endl;
}

void Object::doSomeThingConst() const
{
	std::cout << "do const " << num << std::endl;
}

//main.cpp
#include "Object.h"

int main()
{
	Object a(1);
	const Object b(2);

	a.doSomeThing();
	a.doSomeThingConst();
	//b.doSomeThing();	//error
	b.doSomeThingConst();
}

输出:

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4950467.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-13
下一篇 2022-11-13

发表评论

登录后才能评论

评论列表(0条)

保存