在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,析构函数也执行类似的操作。没有调用new
, delete
, malloc
或类似的任何东西。
从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_a
和a_b
具有相同的寿命。现在我做了什么。
(更新后,我确信)
它似乎表明对没有变量名的构造函数的调用只存在于它们所在的行/语句中(直到;
)。当我考虑函子时,这是有道理的,正如@douglas-o-moen
- "std::function"的简单版本:函数对象的生存期?
- 以延长构造函数外部 QT 对象的生存期
- 在函数调用中C++临时对象的生存期
- 在函数调用中创建的对象的生存期
- 如何为构造函数生成的右值提供左值的生存期
- 为什么常量引用不能延长通过函数传递的临时对象的生存期?
- C++临时对象成员函数的生存期
- 函数内定义的C++对象的生存期
- 用于指示返回值生存期的C++函数属性和参数相同
- 函数中静态变量的生存期
- 为什么临时的生存期延长会导致析构函数被多次调用
- 管理由"std::bind"绑定的成员函数的生存期
- 静态变量生存期、文件范围与函数范围
- 使函数内联是否会影响绑定到其参数的临时变量的生存期
- 在不调用析构函数的情况下结束STL容器的生存期
- 调用了C++对象生存期和析构函数
- 对象生存期内显式构造函数和虚函数调用
- 在c++中,没有变量名的构造函数调用的生存期/作用域是什么?
- 异步函数调用的参数生存期
- 在参数列表中为使用*non*const引用参数的函数创建的临时的生存期是否包含该函数调用