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

C++ 类型为私有数据成员的静态成员,c++,linker-errors,static-members,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

在下面的代码中,类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 }  
我知道我需要在类之外的某个地方定义静态成员。但是由于它的类型是私有成员(并且必须保持私有),我被困在这里,像“a::data*struct_ptr;”这样的东西不起作用

另外,这与StackOverflow中的其他问题不同,因为静态数据成员的类型是定义为私有成员的结构。
非常感谢您提供的任何帮助。

您不能从类外访问私人声明的类型,即使是在某些Cpp文件的文件范围内也不行

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


要定义变量,请使用:

A::data * A::struct_ptr = new data[100];
请注意(第一个)
data
struct\u ptr
之前的
A::
。如果删除任一前缀,编译将失败。它使用两个前缀进行编译


还要注意,如果在构造函数中分配数组,则会出现内存泄漏。每次构造类型为
a
的对象时,都会分配一个新数组

此外,构造函数也有一个问题,它将
struct\u ptr
指向分配数组末尾以外的元素。稍后,您可以访问
struct_ptr
,就好像它指向数组的开头一样。这是行不通的


另一种选择是将
str_ptr
更改为函数,并将静态变量放入其中。这可能类似于:

A::data * A::str_ptr()
{
    static data * const array = new data[100];
    return array;
}
这可能会有所改进,具体取决于您实际需要如何使用此指针。传入索引并让函数返回该索引处的元素可能比较方便


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

“还要注意,如果在构造函数中分配数组,则会出现内存泄漏。每次构造类型为a的对象时,都会分配一个新数组。”静态并不能防止内存泄漏?我认为这将使它成为一个可见的ptr,并被所有对象共享。是吗?@AliJooya是静态的导致了内存泄漏。由于
struct_ptr
是静态的,因此它由
A
的每个实例共享。因此,当构造函数向
struct\u ptr
赋值时,它将覆盖先前运行的任何构造函数编写的内容。(这与初始化不同,因为静态的初始化只会发生一次。但是,初始化发生在定义了静态成员的地方,而静态成员不在构造函数中。)@user207421问题同时提到了链接器错误(“未定义的引用”)和编译器错误(“类似于'a::data*struct_ptr;'的东西不起作用”)。在标头中声明公共不完整类型是OP认为问题所在的一种方法(与类型为私有相关)。@user207421:这是一个链接器错误,因为OP无法定义变量
data*a::struct_ptr
,OP知道这一事实。OP的问题是“如何定义私有类型的变量?”,这是问题的根源,我的答案给出了一种解决方法。
A::data * A::struct_ptr = new data[100];
A::data * A::str_ptr()
{
    static data * const array = new data[100];
    return array;
}