C++ - 将枚举类作为值或 const 引用传递更好吗?

问题描述 投票:0回答:6

因为它被称为“类”,所以我通常会将它作为 const 引用传递,但如果我使用普通枚举,则没有区别,对吧?那么,如果我将枚举类作为值或常量引用传递,会有什么不同吗? 另外,类型重要吗?例如

enum class:int

c++ performance pass-by-value enum-class pass-by-const-reference
6个回答
34
投票

enum class
与常规
enum
一样保存整数值,因此您可以安全地按值传递它,而无需任何开销。请注意,编译器有时也可以通过将其替换为按值传递来优化按引用传递。但是,当不应用这种优化时,通过引用传递可能会导致一些开销。


9
投票

作为一个非常广泛的经验法则,将普通的旧数据类型作为值传递,并将类实例作为

const
引用传递。

此规则也有例外;事实上,当今的流行趋势在构建复制构造函数时喜欢依赖值传递,然后是移动语义

对于 C++11 的新

enum class
内容,按值传递它(毕竟它只在底层保存整数类型)并信任编译器进行优化。

如果您有任何疑问,请描述任何性能差异。


2
投票

通过引用传递实际上是通过指针传递。仅仅因为对该项目的特定引用是恒定的,并不意味着它不能更改。它只是无法通过该引用进行更改。内存位置可能会被其他引用更改。

因此,const 引用和传递值本身之间存在真正的语义差异。

如果这种语义对您所写的内容不起作用,并且您尝试通过 const 引用而不是通过值传递以避免复制,则这不适用于整数或枚举之类的东西(无论枚举上的“class”标签)。你实际上只是通过指针让事情变得更慢。


1
投票

“普通”枚举和枚举类对象都是整型,因此通过 const 引用或按值传递的决定与对整型的其他参数所做的决定相同。

如果一个或另一个“更好”取决于您想要实现的目标,并且持有对对象的引用或获取它的副本不仅仅是空间或“性能”的主题。请注意,存储对对象的(const)引用反映了在任何其他位置对此对象所做的更改,而存储对象的副本则不会。

所以:主要从“引用传递在语义上是否正确”的角度来决定。如果您遇到内存/性能问题,请在无意中更改语义之前使用分析器并进行测量。

无论如何,从内存或性能的角度来看,我认为引用通常会引入一些(可能非常小的)开销,因为访问实际值意味着额外的间接。

从内存角度来看,当“指针”(或引用)用 8 个字节表示时,

int
通常是 4 个字节。但我认为这在函数参数中不应该有太大影响,除非在递归深度非常高的递归函数中有很多这样的参数。

此外,枚举类可以定义其底层数据类型,例如作为一个

unsigned char
,尽管我仍然不认为这在用作函数参数时有多大区别。

enum class ColorsEnumClass : unsigned char {
    red,
    green,
    blue
};

0
投票

一般来说,按值传递会导致对象的复制,而按引用传递则可以避免这种情况。当然,移动语义可以提供帮助。

所以是的,有区别。


-5
投票

是的,不一样。当您按值传递时,您正在创建该值的副本,而当按引用传递时,编译器将指向原始数据。但是优化编译器可以采取一些技巧,因为枚举和枚举类的基础数据类型都是 int。所以这里应用与 int 相同的规则。
在编译时,枚举和枚举类之间存在相当大的差异。 虽然枚举只是数字,但您可以轻松地将枚举与不同的枚举甚至其他类型混合。使用枚举类,您可以一直进行类型检查。考虑以下代码

enum class light_color {red, yellow, green};
enum class car_color {red, yellow, green};

void myFunc(car_color) {}


int main() {
    myFunc(car_color::red);    // this one will compile fine
    myFunc(light_color::red);  // this one will give you error at compile time
}

我可以想到一种场景,其中枚举类型很重要。当您尝试优化空间时,减少枚举大小会产生影响。

© www.soinside.com 2019 - 2024. All rights reserved.