繁体   English   中英

在 C++ 中,没有变量名的构造函数调用的生命周期/范围是多少?

[英]In C++, what is the lifetime/scope of a constructor call without a variable name?

在今天早上的一些编码过程中,我设法输入并编译了类似于以下内容的内容。

void a_function(void)
{
    A_Class(std::string);
    ... //Other code continues
}

(名称已被替换以保护所涉及类的身份)

我想要的是一个命名实例A_Class an_instance(a_string); 我知道在函数结束之前它都会在范围内。 在这个函数中创建的 A_Class 的作用域和生命周期是什么?


我希望我可以在构建阶段做一些聪明的事情,使生命周期几乎成为我想要的任何东西。 在这种情况下,构造函数进行函数调用和 printf ,而析构函数则类似。 没有什么会调用newdeletemalloc或任何类似的东西。

从 C++98 开始,临时变量会一直持续到完整表达式的结尾,除非它的生命周期通过绑定到引用来延长。

我记得,在 ARM(Stroustrup 和 Ellis 的带注释的参考手册)C++ 中,规则是不同的。

通常无法通过在调试器中或通过跟踪语句检查示例来确定标准的保证,因此该问题是有价值的。

只有名字有作用域,所以这个概念在这里无关紧要。

您正在创建一个临时对象。
像所有临时对象一样,它的生命周期一直持续到创建它的完整表达式结束,即直到“;” 在这种情况下,除非它绑定到一个 const 引用变量。

表达方式:

A_Class();

创建一个A_Class类的临时对象。 在对词法上包含它的完整表达式求值后,临时对象被销毁——在这种情况下,临时对象将在其构造后立即被销毁。

为了回答我自己的问题,

第二次尝试

更新的测试代码现在显示为:

#include <iostream>

class Class_A 
{
public:
  Class_A(std::string a_string) 
    : saved_string(a_string)
  {
    std::cout << "Class_A Constructed:" << saved_string << std::endl;
  }
  ~Class_A() 
  {
    std::cout << "Class_A Deconstructed:" << saved_string << std::endl;
  }
  std::string saved_string;
};

class Class_B 
{
public:
  Class_B(std::string a_string) 
    : saved_string(a_string)
  {
    std::cout << "Class_B Constructed:" << saved_string << std::endl;
  }
  ~Class_B() 
  {
    std::cout << "Class_B Deconstructed:" << saved_string << std::endl;
  }
  std::string saved_string;
};


int main () 
{
  std::cout << "Welcome to the lifetime test." << std::endl;
  Class_A a_a("A");
  Class_B a_b("B"); //Now I have to have () here too
  std::cout << "Now for the interesting bit." << std::endl;
  Class_A("a"); //Have to have the ()
  Class_B("b");
  std::cout << "Fin." << std::endl;

  return 0;
}

执行时会产生:

$ ./a.out 
Welcome to the lifetime test.
Class_A Constructed:A
Class_B Constructed:B
Now for the interesting bit.
Class_A Constructed:a
Class_A Deconstructed:a
Class_B Constructed:b
Class_B Deconstructed:b
Fin.
Class_B Deconstructed:B
Class_A Deconstructed:A

所以我现在可以看到生命周期,我不得不在适当的地方使用()或更确切地说("string") 有点奇怪的是a_a()在第一次尝试中是一个函数内部的函数声明,但在第二次尝试中 `a_a_("A") 是一个构造函数。 我不知道允许在其他函数的定义中声明函数,但我想这在某些时候是有意义的,因为你可能在后台有一些奇怪的链接。

未命名临时对象的生命周期仅与它所属的表达式一样长。 直到; .

第一次尝试

我得到了:

class Class_A 
{
public:
  Class_A() 
  {
    std::cout << "Class_A Constructed" << std::endl;
  }
  ~Class_A() 
  {
    std::cout << "Class_A Deconstructed" << std::endl;
  }
};

class Class_B 
{
public:
  Class_B() 
  {
    std::cout << "Class_B Constructed" << std::endl;
  }
  ~Class_B() 
  {
    std::cout << "Class_B Deconstructed" << std::endl;
  }
};

int main () 
{
  std::cout << "Welcome to the lifetime test." << std::endl;
  Class_A a_a();
  Class_B a_b;
  std::cout << "Now for the interesting bit." << std::endl;
  Class_A(); //Have to have the ()
  Class_B();
  std::cout << "Fin." << std::endl;

  return 0;

其中产生:

$ g++ main.cpp
$ ./a.out 
Welcome to the lifetime test.
Class_B Constructed
Now for the interesting bit.
Class_A Constructed
Class_A Deconstructed
Class_B Constructed
Class_B Deconstructed
Fin.
Class_B Deconstructed

所以我只构造了 1 个Class_A 这有点令人困惑,因为我原a_aa_b具有相同的生命周期。 现在我做了什么。
(我确定要跟随更新)

它似乎表明对没有变量名的构造函数的调用仅存在于它们所在的行/语句中(直到; )。 正如@douglas-o-moen 所指出的那样,当我考虑函子时,这是有道理的

暂无
暂无

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

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