简体   繁体   English

为什么在C ++中分离变量定义和初始化?

[英]Why separate variable definition and initialization in C++?

I'm currently working on some quite old C++ code and often find things like 我目前正在研究一些相当古老的C ++代码,并经常发现类似的东西

int i;
i = 42;

or 要么

Object* someObject = NULL;
someObject = new Object();

or even 甚至

Object someObject;
someObject = getTheObject();

I completely understand what this code does but I really have no idea when such a separation of variable definition and initialization could be helpful. 我完全理解这段代码的作用,但我真的不知道变量定义和初始化的这种分离是否有用。 I searched for some explanations but always ended up with member initialization lists or the question when you should define your local variables. 我搜索了一些解释,但总是最终得到成员初始化列表或者应该定义局部变量的问题。

In the end, I don't understand the reason why someone could have intentionally written this code. 最后,我不明白为什么有人可能故意编写这段代码。 It just splits definition and initialization up into two subsequent lines and creates overhead – in the last case it creates an object using the default constructor only to destroy it in the next line. 它只是将定义和初始化分成两个后续行并创建开销 - 在最后一种情况下,它使用默认构造函数创建一个对象,仅在下一行中销毁它。

I wonder whether I should simply change the code to 我想知道我是否应该简单地将代码更改为

int i = 42;
Object* someObject = new Object();
Object someObject = getTheObject();

Could this lead to any problems? 这会导致任何问题吗?

Object someObject;
someObject = getTheObject();

This uses the assignment operator. 这使用赋值运算符。

Object someObject = getTheObject();

This uses the copy constructor. 这使用了复制构造函数。

Apart from that, your suggested changes are equivalent, and you should implement them. 除此之外,您建议的更改是等效的,您应该实现它们。 The copy ctor/assignment operator difference is expected to produce the same result, this is not enforced by the language though. 复制ctor /赋值运算符的差异预计会产生相同的结果,但这并不是由语言强制执行的。

I see no valid reason to split up declaration and assignment like the original code does - even though for all practical purposes it doesn't introduce overhead (except for the object) 我认为没有正当理由像原始代码那样拆分声明和赋值 - 即使出于所有实际目的,它也不会引入开销(除了对象)

In C, there is the restriction that you have to define your variables at the top of the code block, even if you only need them somewhere later on in the function. 在C中,您必须在代码块的顶部定义变量,即使您稍后在函数中只需要它们。 So in the old days of C, people often first defined all their variables and then later though about the values they should have. 因此,在C的旧时代,人们通常首先定义所有变量,然后再定义他们应该拥有的值。

Since you say it is quite old C++ code, it might use that same convention as a holdover from C practices. 既然你说它是相当古老的C ++代码,它可能会使用与C实践中的保留相同的约定。

There is no real reason to do this in C++, though. 但是,在C ++中没有真正的理由这样做。 Better always define your variables where you can initialize them directly. 最好总是定义您可以直接初始化它们的变量。

The change you propose is highly recommended! 强烈建议您提出改变! This is part of an important idiom in C++ programming, namely Resource Acquisition Is Initialization . 这是C ++编程中一个重要习语的一部分,即资源获取是初始化

There is a good technical reason on ROM-based hardware, it is NOT a style issue: 基于ROM的硬件有一个很好的技术原因,它不是样式问题:

On ROM/EEPROM based embedded systems, this has an effect on where in the binary the value is written. 在基于ROM / EEPROM的嵌入式系统中,这会影响二进制值的写入位置。 Uninitialized variables are written into .bss, whereas initialized variables are written into .data. 未初始化的变量写入.bss,而初始化的变量写入.data。 Premature initialization will bloat your ROM space, which on older embedded systems can get you into big, big trouble. 过早的初始化会使你的ROM空间膨胀,这在旧的嵌入式系统上可能会给你带来巨大的麻烦。 If you are running on a system with a small ROM, you can run out of memory if you initialize needlessly. 如果您在具有小ROM的系统上运行,则在不必要地初始化时可能会耗尽内存。 Some goofy compilers will even address directly into the ROM, making these values effectively read-only if you are not careful. 一些愚蠢的编译器甚至可以直接写入ROM,如果你不小心,这些值有效地只读。

eg See this GameBoy example for a more thorough explanation: http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_varinit 例如,请参阅此GameBoy示例以获得更详尽的解释: http//www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_varinit

Consider the following case: 考虑以下情况:

SomeType object;
if( whateverCondition ) {
   object = getObjectOneWay();
} else {
   object = getObjectAnotherWay();
}

this way it's clear that both branches assign the variable and its initial value is irrelevant. 这样很明显,两个分支都分配变量,其初始值是无关紧要的。 It's rarely worth that however. 然而,这很少值得。

int i;
i = 42;

That is not separate variable definition and initialization . 这不是单独的变量定义和初始化

That is separate variable declaration and assignment . 这是单独的变量声明和赋值 I don't see any reason for this. 我没有看到任何理由。 If you know the value at the time of declaration of variable, then initialize it right then. 如果您知道变量声明时的值,那么就将其初始化。 So your question doesn't has any rationale explanation. 所以你的问题没有任何理由解释。

Of course, if you don't know the value at the time of declaration, then you don't have any choice, you need assignment then. 当然,如果您在申报时不知道价值,那么您没有任何选择,那么您需要分配

Why separate variable definition and initialization in C++? 为什么在C ++中分离变量定义和初始化?

You haven't separated definition and initialization. 您还没有分离定义和初始化。 You have just assigned the variable/object (to some particular) value in your code snippet. 您刚刚在代码段中分配了变量/对象(某些特定的)值。 So the title is misleading. 因此标题具有误导性。

Object someObject;
someObject = getTheObject();

is quite different from Object someObject = getTheObject(); Object someObject = getTheObject();完全不同Object someObject = getTheObject();

someObject = getTheObject(); invokes the assignment operator of Object class whereas in Object someObject = getTheObject(); 调用Object类的赋值运算符,而在Object someObject = getTheObject(); copy constructor of the class gets invoked. 调用类的复制构造函数。 This is also known by the name copy initialization 这也称为复制初始化名称

A good compiler might generate the same code in case of int i; i = 42; 一个好的编译器可能会在int i; i = 42;情况下生成相同的代码int i; i = 42; int i; i = 42; and int i =42 . int i =42 There won't be much of an overhead. 不会有太大的开销。

BTW I always prefer int i = 42 to int i; i=42 BTW我总是喜欢int i = 42int i; i=42 int i; i=42 and int i; i=42

Object someObject = getTheObject(); to

Object someObject; someObject = getTheObject();

PS : int i = 42 defines and initializes i whereas int i; i=42 PS: int i = 42定义并初始化iint i; i=42 int i; i=42 defines i and then assigns 42 to it. int i; i=42定义i ,然后为其分配42

No. It's a matter of style. 不,这是一个风格问题。

However if he ever wanted to move the declaration out of the function it would be less editing if the declaration and initialization is seperated. 但是,如果他想要将声明移出函数,那么如果声明和初始化是分开的,那么编辑就会少一些。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM