在下面的代码中,类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中的其他问题不同,因为静态数据成员的类型属于定义为私有成员的结构。 我们非常感谢您的帮助。
答案 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;
}