类型为私有数据成员的静态成员

时间:2019-02-06 00:09:08

标签: c++ linker-errors static-members

在下面的代码中,类A具有一个私有数据成员。我需要定义一个具有这种结构的数组,并在A类的所有对象之间共享整个数组。因此,我定义了一个指向该结构的指针,并将其初始化为该类的构造函数。

然后,该类的两个实例以其自己的偏移量访问静态数组。

1 #include<iostream>
2 #include<cstdio>
3 
4 using namespace std;
5 
6 class A{
7 
8     private:
9 
10         struct data
11         {
12             int id;
13         };
14         struct data   *str_offset;
15     public:
16         A();
17         static data* struct_ptr;
18 
19         int get_next()
20         {
21             int tmp =str_offset->id;
22             str_offset ++;
23             return tmp;
24         }
25         void set_ptrs(int str)
26         {
27             str_offset = struct_ptr + str;
28         }
29 };
30 
31 A::A()
32 {
33    struct_ptr = new A::data[100];
34 
35    for (int i=0; i<100; i++)
36    {
37        struct_ptr->id = i;
38        struct_ptr++;
39    }
40 }
41 
42 int main()
43 {
44     int size = 100;
45     int v1_st = 0;
46     int v2_st = 50;
47 
48 
49     A v1, v2;
50     v1.set_ptrs(v1_st);
51     v2.set_ptrs(v2_st);
52 
53     for( int i = 0; i < 10; i++)
54     {
55         cout << "v1[" << i << "] = " << v1.get_next() << endl;
56         cout << "v2[" << i << "] = " << v2.get_next() << endl;
57     }
58 
59 }  

编译并链接代码时,出现此错误:

/cache//ccz4iAcr.o: In function `A::A()':
static_test.cpp:(.text+0x19): undefined reference to `A::struct_ptr'
static_test.cpp:(.text+0x29): undefined reference to `A::struct_ptr'
static_test.cpp:(.text+0x35): undefined reference to `A::struct_ptr'
static_test.cpp:(.text+0x40): undefined reference to `A::struct_ptr'
/cache//ccz4iAcr.o: In function `A::set_ptrs(int)':
static_test.cpp:(.text._ZN1A8set_ptrsEi[_ZN1A8set_ptrsEi]+0xe): 
undefined reference to `A::struct_ptr'
collect2: error: ld returned 1 exit status   

我知道我需要在类之外的某个地方定义静态成员。但是由于它的类型是私有成员(并且必须保持私有),所以我被困在这里,类似于“ A :: data * struct_ptr;”。不起作用。

P.S。这与StackOverflow中的其他问题不同,因为静态数据成员的类型属于定义为私有成员的结构。 我们非常感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

要定义变量,请使用:

A::data * A::struct_ptr = new data[100];

在第一个A::data之前注意struct_ptr。如果删除任一前缀,编译将失败。具有两个前缀,它将编译。

还请注意,如果在构造函数中分配数组,则会发生内存泄漏。每次构造A类型的对象时,您将分配一个新数组。

此外,您的构造函数还有一个问题,就是它使struct_ptr指向分配数组末尾的元素。以后,您访问struct_ptr就像指向数组的开始一样。这是行不通的。


另一种选择是将str_ptr更改为一个函数,然后将静态变量放入其中。可能是这样的:

A::data * A::str_ptr()
{
    static data * const array = new data[100];
    return array;
}

根据您实际需要使用此指针的方式,可以对此进行改进。传入索引并让函数返回该索引处的元素可能会很方便。

您可能还想定义一个包含数据数组的类,以便它可以处理初始化。这样,您不必多次进行初始化,也不必跟踪是否已初始化任何东西。 (至少将指针定义为const可以防止将其值更改为意外值。)

答案 1 :(得分:0)

即使在某些Cpp文件的文件范围内,也不能从类外部访问私有声明的类型。

要克服这一点,您可以在类外声明类型(但要对其进行某种程度的封装,请在CPP文件中定义它):

// header file
class A{
private:

    struct data   *str_offset;
public:
    A();
    static data* struct_ptr;
};

// cpp-file:
struct data
{
    int id;
};

data * A::struct_ptr = new data[100];

A::A() {
    str_offset = struct_ptr++;
    str_offset->id = 10;
}