gpt4 book ai didi

c++ - C/C++ 稀有关键字 - register、volatile、extern、explicit

转载 作者:IT老高 更新时间:2023-10-28 22:32:39 29 4
gpt4 key购买 nike

您能否简要介绍一下这 4 个关键字的用途和原因?

我了解 google 会告诉您的关于 register 和 volatile 的基本知识,但想了解更多(只是一个实用的概述)。外部和显式让我有点困惑,因为尽管做了相当低级的嵌入式系统代码,但我从来没有找到自己必须使用它们的理由。再说一次,我可以用谷歌搜索,但我更喜欢专家提供的快速实用的总结,以便牢记在心。

最佳答案

外部

extern 被重载用于多种用途。对于全局变量,这意味着它是在声明变量,而不是定义它。这对于将全局变量放在标题中很有用。如果你把它放在标题中:

int someInteger;

每个包含该 header 的 .cpp 文件都会尝试拥有自己的 someInteger。这将导致链接器错误。通过用 extern 声明它,你的意思是在代码的某处会有一个 someInteger:

extern int someInteger;

现在,在一个 .cpp 文件中,您可以定义 int someInteger,这样就会有一个拷贝。

还有extern "C",用于指定某些函数使用C-linkage规则而不是C++。这对于与编译为 C 的库和代码进行交互非常有用。

在 C++0x 中,还会有 extern template 声明。这些与显式模板实例化相反。当你这样做时:

template class std::vector<int>;

你现在告诉编译器实例化这个模板。通常,实例化会延迟到第一次使用模板。在 C++0x 中,你可以说:

extern template class std::vector<int>;

这告诉编译器不要在这个 .cpp 文件中实例化这个模板,ever。这样,您可以控制模板在哪里被实例化。明智地使用它可以大大缩短编译时间。

显式

这用于防止类型的自动转换。如果您有一个具有以下构造函数的类 ClassName:

ClassName(int someInteger);

这意味着如果你有一个接受 ClassName 的函数,用户可以用 int 调用它,转换将自动完成。

void SomeFunc(const ClassName &className);
SomeFunc(3);

这是合法的,因为 ClassName 有一个采用整数的转换构造函数。这就是采用 std::string 的函数也可以采用 char* 的方式; std::string 有一个构造函数,它接受一个 char*

但是,大多数时候您不希望这样的隐式转换。您通常只希望转换是明确的。是的,它有时与 std::string 一样有用,但您需要一种方法将其关闭以处理不适当的转换。输入显式:

explicit ClassName(int someInteger);

这将防止隐式转换。您仍然可以使用 SomeFunc(ClassName(3));SomeFunc(3) 将不再工作。

顺便说一句:如果 explicit 对您来说很少见,那么您使用它还不够。您应该始终使用它,除非您特别想要转换。这并不常见。

易变

这会阻止某些有用的优化。通常,如果你有一个变量,C/C++ 会假设它的内容只有在显式改变它们时才会改变。所以如果你把一个int someInteger;声明为一个全局变量,C/C++编译器可以在本地缓存这个值,而不是每次你使用它时都不断地访问这个值。

有时,您想阻止这种情况。在这些情况下,您使用 volatile;这会阻止这些优化。

注册

这只是一个提示。它告诉编译器尝试将变量的数据放入寄存器。这基本上是不必要的;编译器比你更擅长决定什么应该和不应该是寄存器。

关于c++ - C/C++ 稀有关键字 - register、volatile、extern、explicit,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6852522/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com