范围引起的对象的C ++条件存储分配 [英] C++ conditional storage allocation for object caused by scope

查看:223
本文介绍了范围引起的对象的C ++条件存储分配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前我正在阅读 Think in C ++



对象的存储分配。



下面的代码中, goto switch 生成警告或错误



if-else 工作正常,执行期间有条件地传递。



那么为什么 if-else 没有警告或错误?

  / * crosses initializaion错误* / 
#include< iostream>
using namespace std;
class X {
public:
X();
};
X :: X(){}

void f(int i){
if(i> 2){
X x1;
} else {
X x2; //为什么有条件地执行工作正常?
}
if(i> 2){
goto jjump1;
}
// X x3; //错误coused by goto
{X x3; // works fine}
jjump1:
X x4;
switch(i){
// case 1:X x5;打破;
// case 2:X x6;打破; //错误coused by switch
{case 1:X x5; break;}
{case 2:X x6; break;} // removed

}
}
int main(){
f(1);
return 0;
}

UPDATE:



这样做是为了保证一个对象不能被创建,除非它也被初始化。但是在 if-else 如何可以将它的两部分初始化为只有一部分它会通过?



由于C ++遵循为范围的开始大括号分配范围的存储的C中的做法。

这是我的想法(我不知道是什么错误..):



但是对于 switch goto ,只有令牌的情况需要初始化,但是有交叉初始化错误。 if-else 切换都只遵守仅初始化记号分支。



最后,我想出了关键词是 scope 由于C ++遵循在C中为范围的开始大括号分配存储的做法。因此,从具有自动存储持续时间的变量的点跳转的程序除非变量具有标量类型,具有简单的默认构造函数和简单析构函数的类类型,这些类型之一的cv限定版本或者这些类型之一的数组,否则不在范围之内,前面的类型之一并且没有初始化规则的情况下确保变量在分配后被初始化



谢谢大家。

解决方案

通过变量的声明,除非它是标量或它有一个琐碎的默认构造函数,这是在草案C ++标准部分 6.7



可以传入一个块,但不能以初始化的方式绕过声明。一个程序跳过 87 从自动存储持续时间的变量不在范围内的点到它在范围内的点,除非变量具有标量类型,类类型具有普通默认构造函数和一个简单析构函数,这些类型之一的cv限定版本或者前面类型之一的数组,并且没有初始化器(8.5)。



切换的情况下,避免此问题的一种方法是使用 {}

  switch(i)
{
case 1:{X x5;打破; }
case 2:{X x6;打破; }
}


Currently I'm reading Think in C++.

I'm confused about the conditional storage allocation for an object.

As the code below, the goto and switch generate warning or an error.

But if-else works fine, which is conditionally passed through during execution.

So why there is no warning or error for if-else?

/* crosses initializaion error */  
#include <iostream>
using namespace std;
class X {
public:
    X();
};
X::X() {}

void f(int i) {
    if (i > 2) {
       X x1;
    } else {
       X x2; // why conditionally executed works fine?
    }
    if (i > 2) {
        goto jjump1;
    }
    //X x3;  // error coused by goto
    {X x3; //works fine}
jjump1:
    X x4;
    switch(i) {
      // case 1:    X x5; break;
     //case 2:  X x6; break; // error coused by switch
       {case 1: X x5; break;}
       {case 2: X x6; break;}//  solved

    }
 }
int main() {
    f(1);
    return 0;
}

UPDATE:

C++ doing so is to guarantee that an object cannot be created unless it is also initialized. But in the case of if-else how can both part of it be initialized as only one part of it will be go through?

As the C++ is following the practice in C of allocating the storage for a scope at the opening brace of that scope.

Here is my thought(I don't know what's wrong..):

But it's the same for switch and goto, only the token case need to be initialized but there is crosses initialization error. The if-else and switch both obey initializing the token branch only.

At last, I figured out the key word is scope. As the C++ is following the practice in C of allocating the storage for a scope at the opening brace of that scope. So the A program that jumps87 from a point where a variable with automatic storage duration is not in scope to a point where it is in scope is ill-formed unless the variable has scalar type, class type with a trivial default constructor and a trivial destructor, a cv-qualified version of one of these types, or an array of one of the preceding types and is declared without an initializer rule ensure that variables are initialized once allocated.

Thank you all.

解决方案

You are not allowed to jump past the declaration of a variable unless it is scalar or it has a trivial default constructor, this is covered in the draft C++ standard section 6.7:

It is possible to transfer into a block, but not in a way that bypasses declarations with initialization. A program that jumps87 from a point where a variable with automatic storage duration is not in scope to a point where it is in scope is ill-formed unless the variable has scalar type, class type with a trivial default constructor and a trivial destructor, a cv-qualified version of one of these types, or an array of one of the preceding types and is declared without an initializer (8.5).

In the case of the switch one way to avoid this problem would be to create a scope using {} at each label like this:

switch(i)
{
   case 1: { X x5;  break; }
   case 2: { X x6;  break; }
}

这篇关于范围引起的对象的C ++条件存储分配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆