静态变量阴影全局

时间:2017-11-15 15:53:34

标签: c++ c++11 scope static initialization

我正在尝试使用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;
}

我在global array中创建了一个名为arr的array和另一个名为arr的{​​{1}}。似乎当我执行B时,正在使用的placement new来自类,因为我认为是链接器错误。

为什么会这样?为什么不使用arr?如果我更改global arr以使用我重命名的placement new,则可以使用。我认为它必须与global array做点什么,但我没有具体的答案。

2 个答案:

答案 0 :(得分:1)

来自C ++ 2017标准(12.2.3.2静态数据成员)

  

2在其类中声明非内联静态数据成员   定义不是定义,可能是其他类型的不完整定义   比cv void。静态数据成员的定义不是   类定义中的内联定义应出现在命名空间中   封闭成员类定义的范围。在定义中   命名空间范围,静态数据成员的名称应该是合格的   通过使用::运算符的类名。 初始化表达式   在静态数据成员的定义中是在其范围内   class (6.3.7)。

所以在这个静态数据成员的定义中

const A* B::a_obj = new(arr) A;

首先在类arr的范围内搜索非限定名称B。而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

答案 1 :(得分:1)

原因是arr属于B类,而不是全局范围是由于非限定名称查找规则。

具体来说:

  

静态数据成员定义用于定义a的名称   静态数据成员,查找的方式与使用的名称相同   成员函数的定义。

含义:

struct X {
    static int x;
    static const int n = 1; // found 1st
};
int n = 2; // found 2nd.
int X::x = n; // finds X::n, sets X::x to 1, not 2

如果您有兴趣,可以在此处查看更多信息: http://en.cppreference.com/w/cpp/language/unqualified_lookup

正如人们建议你得到你想要的东西:

const A* B::a_obj = new(::arr) A;
相关问题