栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++ 使用const而不是#define

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++ 使用const而不是#define

引入

在《Effective C++》一书中的第二个条款,作者让我们尽量以const,enum,inline替换#define,换种说法就是“宁可以编译器替换预处理器”比较好。在一些基础性的文章内,我也是看到了将#define声明的宏视作为常量的作者,这里并不止针对一位作者,而是许多。或许,宏未被编译器所看见,在编译之前就可能编译器已经将所有宏替换了。

为什么使用const代替#define 1.作用域

#define并不注重作用域,封装作为面向对象的一部分,这样的操作为使得我们设计的类暴露出来,为了提供封装性,我们可以使用const成员变量代替#define
使用#define写的一段代码

#include 

#define MAX_SIZE 20
class BankQueue {
public:
	BankQueue() = default;
	BankQueue(BankQueue&) = delete;
	BankQueue(BankQueue&&) = delete;
	int max_size() {
		return MAX_SIZE;
	}
};

int main() {
	BankQueue bq;
	std::cout << bq.max_size() << std::endl;
	std::cout << MAX_SIZE << std::endl;
	return 1;
}

懂点面向对象编程都知道,max_size是用于获取某个私有成员的接口,但是我们并不能提供private:#define…的操作,为了封装数据,我们应该使用const成员变量代替
使用const成员变量

#include 

class BankQueue {
public:
	BankQueue() = default;
	BankQueue(BankQueue&) = delete;
	BankQueue(BankQueue&&) = delete;
	int max_size() {
		return max_size_;
	}
private:
	static const int max_size_ = 20;
};

int main() {
	BankQueue bq;
	std::cout << bq.max_size() << std::endl;
	return 1;
}

我们对max_size进行了封装,是使用的const而不是#define,此时我们只能通过max_size()获取max_size_了。

2.指针操作

#define在编译期前就被编译器全部替换,这样导致我们不能使用指针来对宏操作,例如。

#include 

#define THREAD_MAX_SIZE 8

int main() {
	int* p = &THREAD_MAX_SIZE;
	std::cout << *p;
	return 1;
}

这段代码是错误的,因为THREAD_MAX_SIZE是一个右值,但是操作数必须要是左值,但是我们能通过const将指针成功赋值。

#include 

const int thread_max_size = 20;

int main() {
	const int* p = &thread_max_size;
	std::cout << *p;
	return 1;
}

注意,指针p声明最前面的const代表所指的数据是一个常量。

3.#define的缺陷

既然#define在编译期前就被替换,我们也可以卡它的BUG

#include 

#define MIN_SIZE 0
#define MAX_SIZE 10
#define LENGTH MAX_SIZE - MIN_SIZE

int main() {
	
	std::cout << LENGTH << std::endl;

	return 1;
}

输出:10
这个结果在意料之中,那么我们换一个数字试试

#include 

#define MIN_SIZE 2
#define MAX_SIZE 20
#define LENGTH MAX_SIZE - MIN_SIZE

int main() {
	
	std::cout << LENGTH / 2 << std::endl;

	return 1;
}

我想找到中间的那个size,不过分吧。
用长度除2,输出结果是19而不是9
编译器在编译期前将整个程序替换为

#include 

#define MIN_SIZE 2
#define MAX_SIZE 20
#define LENGTH 20 - 2

int main() {
	
	std::cout << 20 - 2 / 2 << std::endl;

	return 1;
}

这样错的就很显然了。

总结

尽量使用const代替#define!不要犟。
不要将#define认作为常量,它可能从来没被编译器看到过。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1010473.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号