C++中静态方法的局部变量范围
Scope of variable local to static method in C++
我试图使用私有构造函数创建一个对象的实例。这种方法正确吗?
#include <iostream>
using namespace std;
class A{
int y;
A(int y=2):y(y){};
public:
A(const A &obj){
cout<<"copy Cotr is called"<<endl;
this->y=obj.y;
}
int* addr(){
int *a=&y;
return a;
}
static A create(int y1=2){
class A a(y1);
cout<<&a<<endl;
return a;
}
void print(){
cout<<y<<endl;
}
};
int main(){
A o1=A::create(1);
A o2=A::create(3);
cout<<&o1<<" "<<&o2<<endl;
return 0;
}
输出为:
0x7ffd20d2f280
0x7ffd20d2f284
0x7ffd20d2f280 0x7ffd20d2f284
在上面的代码中,我无法理解几点:
create()
返回一个值,所以在A o1=A::create(1);
中发生的赋值期间,应该调用复制构造函数,但事实并非如此。 为什么?- 这是一些未定义的行为,因为在
create()
和main()
中创建的对象的地址是相同的,并且create()
中的对象是本地的,并且在函数结束后超出范围。
- (( 返回一个值,因此在
A o1=A::create(1);
中发生的赋值期间,应该调用复制构造函数,但事实并非如此。
您有复制消除(演示(,这是标准允许的优化。
对象直接在最终位置构造,不进行复制/移动。
在 C++17 中,一些复制省略甚至是强制性的。(在你的情况下有一半(。
- 这是一些未定义的行为,因为在 create(( 和 main(( 中创建的对象的地址是相同的,并且 create(( 中的对象是本地的,并且在函数结束后超出范围。
使用复制省略,由于对象是直接在最终位置构造的,因此确实只有一个地址,就好像create
的局部变量是来自main
的地址一样。
这个:
A a = x();
与此不同:
A a;
a = x();
在第二种情况下,您有副本,在第一种情况下,您没有。
为了回答你的第二个问题,在create((中创建的对象是本地的,但随后它被复制回调用者(实际上是移动的(。由于堆栈帧相同,因此本地地址相同。但是当它被复制时,你有两个不同的对象。
感谢您的所有答案。深入研究它,现在回答我自己的问题。
对于有学问的人:
这是第 17 C++中复制省略的主要实例。
答案结束了。对于仍然不明白的人:
此方法没有错误,并且不显示任何未定义的行为。如今,大多数编译器都使用C++11或C++17,它与复制省略(复制省略(很好地集成在一起。
create(( 返回一个值,因此在赋值期间发生在 A o1=A::create(1(;,应该调用复制构造函数,但它不是。为什么?
不调用复制构造函数,因为返回类型是 prvalue(纯右值(,编译器优化程序的方式是将返回值直接创建到存储中,否则函数的返回值将被复制或移动到该存储中。因此,实际上不会发生移动或复制,因此不会调用移动/复制构造函数。即使在create()
结束后,也不会调用析构函数。
这是一些未定义的行为,作为所创建对象的地址吗 在 create(( 和 main(( 中是相同的,而 create(( 中的对象是本地的 并在函数结束后超出范围。
因此,即使在函数create()
结束后,对象也不会被推出范围,或者不会调用该对象的析构函数。因为对象不是在create()
而是在main()
本身中创建的。它不是一个未定义的行为,而是C++的一个主要好处,因为不需要声明或调用不必要的指针和函数。在这里,NRVO发生。
- 在 return 语句中,当操作数是 具有自动存储持续时间的非易失性对象,不是 函数参数或 catch 子句参数,属于 与函数返回的类类型相同(忽略 CV 限定( 类型。这种复制省略的变体被称为NRVO,"命名返回 价值优化"。
- 使用的未初始化局部变量'Quick'
- 修复未初始化的局部变量错误
- 局部变量保留函数中的值
- 如何使用 C++ 中的继承函数访问派生类中的局部变量
- 将引用分配给局部变量,如果局部变量超出范围,它会超出范围吗?
- C++中静态方法的局部变量范围
- 离开范围后如何保护局部变量的值?
- 在其范围之外使用局部变量
- 将局部变量保存到全局向量中,为什么离开局部范围后可以得到这些局部变量?
- 尝试声明函数的局部变量,但得到范围错误
- 局部变量超出范围..我认为
- 变量循环范围会导致返回局部变量的地址引用
- C++ 中静态局部变量的范围和生存期
- 从 Outsie it 范围 C++ 访问局部变量
- 在范围内存在不可复制的局部变量时按值捕获
- Lambdas和引用捕获局部变量:在范围之后访问
- 指针可以将局部变量的内存指向其范围之外?
- 是否可以在其范围之外访问局部变量的内存?
- 如何在C++的另一个范围内使用局部变量
- 在类范围内声明与类属性同名的局部变量