Local variable scope question

给你一囗甜甜゛ 提交于 2019-11-28 13:29:46

You quoted standard correctly. Let me emphasize:

A name declared in a block is local to that block. Its potential scope begins at its point of declaration and ends at the end of its declarative region.

You didn't declare any name, actually. Your line

MyClass (12345);

does not even contain a declaration! What it contains is an expression that creates an instance of MyClass, computes the expression (however, in this particular case there's nothing to compute), and casts its result to void, and destroys the objects created there.

A less confusing thing would sound like

call_a_function(MyClass(12345));

You saw it many times and know how it works, don't you?

The object created in your

MyClass(12345);

is a temporary object which is only alive in that expression;

MyClass m(12345);

is an object which is alive for the entire block.

You're actually creating an object without keeping it in scope, so it is destroyed right after it is created. Hence the behavior you're experiencing.

You can't access the created object so why would the compiler keep it around?

To answer your other questions. The following is the invocation of the comma operator. It creates a MyClass temporary, which includes calling its constructor. It then evaluates the second expression cout << "Y" << endl which will print out the Y. It then, at the end of the full expression, will destroy the temporary, which will call its destructor. So your expectations were right.

MyClass (12345), cout << "Y" << endl;

For the following to work, you should add parentheses, because the comma has a predefined meaning in declarations. It would start declaring a function some_func returning an int and taking no parameters and would assign the scoped_lock object to x. Using parentheses, you say that the whole thing is a single comma operator expression instead.

int x = (boost::scoped_lock (my_mutex), some_func()); // still multi-thread safe

It should be noted that the following two lines are equivalent. The first does not create a temporary unnamed object using my_mutex as the constructor argument, but instead the parentheses around the name are redundant. Don't let the syntax confuse you.

boost::scoped_lock(my_mutex);
boost::scoped_lock my_mutex;

I've seen misuse of the terms scope and lifetime.

  • Scope is where you can refer to a name without qualifying its name. Names have scopes, and objects inherit the scope of the name used to define them (thus sometimes the Standard says "local object"). A temporary object has no scope, because it's got no name. Likewise, an object created by new has no scope. Scope is a compile time property. This term is frequently misused in the Standard, see this defect report, so it's quite confusing to find a real meaning.

  • Lifetime is a runtime property. It means when the object is set up and ready for use. For a class type object, the lifetime begins when the constructor ends execution, and it ends when the destructor begins execution. Lifetime is often confused with scope, although these two things are completely different.

    The lifetime of temporaries is precisely defined. Most of them end lifetime after evaluation of the full expression they are contained in (like, the comma operator of above, or an assignment expression). Temporaries can be bound to const references which will lengthen their lifetime. Objects being thrown in exceptions are temporaries too, and their lifetime ends when there is no handler for them anymore.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!