我正在尝试使用 placement new
创建一个对象(我知道使用智能指针,这只是为了学习)。我的代码如下:
#include <vector>
#include <iostream>
#include <memory>
using namespace std; // please excuse this
// if you change like 19 to arr1 (or any other var name) instead of arr and line 40 to arr1 then it works
struct A
{
int in = 999;
A()
{cout << "A ctor\n";}
~A()
{cout << "A dtor\n";}
};
char arr[sizeof(A)];
class B
{
public:
static char arr[sizeof(A)];
const static A* a_obj;
B()
{
cout << "B ctor\n";
//cout << (a_obj->in) << endl;
}
~B()
{
cout << "B dtor\n";
}
};
const A* B::a_obj = new(arr) A;
int main()
{
B g;
}
我在 B
中创建了一个名为 arr 的 global array
和另一个名为 arr
的array
。似乎当我执行 placement new
时,正在使用的 arr
来自类,因为我认为是链接器错误。
为什么会这样?为什么不使用 global arr
?如果我更改 placement new
以使用我重命名的 global array
它会起作用。我认为它必须对 lookups
做些什么,但我没有具体的答案。
最佳答案
来自 C++ 2017 标准(12.2.3.2 静态数据成员)
2 The declaration of a non-inline static data member in its class definition is not a definition and may be of an incomplete type other than cv void. The definition for a static data member that is not defined inline in the class definition shall appear in a namespace scope enclosing the member’s class definition. In the definition at namespace scope, the name of the static data member shall be qualified by its class name using the :: operator. The initializer expression in the definition of a static data member is in the scope of its class (6.3.7).
所以在这个静态数据成员的定义中
const A* B::a_obj = new(arr) A;
首先在类B
的范围内搜索非限定名称arr
。而B类确实声明了这样一个名字
static char arr[sizeof(A)];
如果要使用全局命名空间中的名称,则使用限定名称
const A* B::a_obj = new(::arr) A;
这是一个演示程序
#include <iostream>
struct A
{
const static int N = 10;
static int n1;
static int n2;
};
const int N = 20;
int A::n1 = N;
int A::n2 = ::N;
int main()
{
std::cout << "A::n1 = " << A::n1 << std::endl;
std::cout << "A::n2 = " << A::n2 << std::endl;
return 0;
}
它的输出是
A::n1 = 10
A::n2 = 20
关于c++ - 静态变量阴影全局,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47311823/