C++ 类型为私有数据成员的静态成员
在下面的代码中,类A有一个私有数据成员。我需要定义这样一个结构的数组,并在类A的所有对象之间共享整个数组。因此,我定义了一个指向该结构的指针,并将其初始化为类的构造函数 然后,该类的两个实例使用自己的偏移量访问静态数组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
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;
}