我可以在不结束块的情况下终止C ++变量的范围吗?

时间:2011-02-25 00:38:08

标签: c++ variables scope

我想做类似以下的模式:

T* const pT = findT();
// Do some work
T* const pT2 = new T( *pT );
// Mutate the object pT2 refers to
delete pT;
// At this point, I want the scope of pT to end.
// I do not want the scope of pT2 to end

我知道我可以通过结束一个块来结束范围,但它最终会像这样结束:

T* pT2 = 0;
{
    T* const pT = findT();
    // Do some work
    pT2 = new T( *pT );
    // Mutate the object pT2 refers to
    delete pT;
}

这会导致pT2失去const限定符,因为我必须在声明之后分配它。

我想要我的蛋糕,我也想吃它,我想要明确的常量正确的范围!

除了结束一个块之外,还有什么方法可以结束变量的范围吗?如果没有,是否有任何计划扩展标准以支持这一点?

5 个答案:

答案 0 :(得分:4)

你可以使用lambdas:

T* const pT = []() -> T* {
    T* pT;
    // Do whatever the hell you want with pT
    return pT;
}();

答案 1 :(得分:3)

  

除了结束一个块之外,有没有办法在变量上结束范围?

没有。局部变量的范围在声明时开始,并在声明它的块的末尾结束。

  

如果没有,有没有计划扩展标准以支持这个?

这听起来是一个非常糟糕的主意:这会增加关于范围,名称查找和对象生存期的规则的不必要的复杂性。

答案 2 :(得分:0)

你所谓的“块”是C ++中“范围”的另一个名称。 如何在C ++中定义范围。

此处的另一个选择是使用std::auto_ptr,在转让时转让所有权。旧指针不会清理,但实际上是零。

答案 3 :(得分:0)

没有。然而,您可以使用以下习语来稍微美化您的示例(好吧,这是主观的,但是嘿):

T* p1 = 0;

if (T* const p2 = findT()) {
  p1 = new T( *p2 );
  delete p2;
}

答案 4 :(得分:0)

您可以使用std::optional(或boost::optional)对对象的生命周期进行精细控制。

这里是一个例子:

std::optional< ClassA > a(std::in_place, 1); // ClassA constructor is called
std::optional< ClassB > b(std::in_place, 2); // ClassB constructor is called
a.reset(); // ClassA destructor is called
b.reset(); // ClassB destructor is called

不幸的是,该变量的名称仍然存在,并且其内存仍在分配。

还有一个技巧来销毁字符串并释放其内存(变量本身仍然存在):

std::string my_str;
std::string{}.swap(my_str); // likely to free the memory

它是由实现定义的,因此它实际上可能不会释放内存,但很可能会这样做。