Reputation: 95
In the code below, class A has a private data member. I need to define an array of such structure and share the whole array between all the objects of class A. So, I have defined a pointer to the struct and initialized it the constructor of the class.
Then two instances of the class access the static array with their own offset.
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 }
When I compile and link the code, I get this error:
/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
I understand that I need to define the static member somewhere outside the class. But as its type is of a private member (and has to remain private), I am stuck here and something like "A::data* struct_ptr;" doesn't work.
P.S. This is different from other questions in StackOverflow as the type of the static data member is of a struct defined as a private member. Any help is highly appreciated.
Upvotes: 2
Views: 119
Reputation: 17007
To define the variable use:
A::data * A::struct_ptr = new data[100];
Note the A::
before both (the first) data
and struct_ptr
. If you drop either prefix, the compilation will fail. With both prefixes, it compiles.
Also note that if you allocate the array in the constructor, you have a memory leak. You would allocate a new array each time you construct an object of type A
.
Also, your constructor has an issue in that it leaves struct_ptr
pointing to the element past the end of the allocated array. Later you access struct_ptr
as if it was pointing to the start of the array. This is not going to work.
Another option would be to change str_ptr
to a function, and put the static variable in there. This might be something like:
A::data * A::str_ptr()
{
static data * const array = new data[100];
return array;
}
This can probably be improved, depending on how you really need to use this pointer. It might be convenient to pass in an index and have the function return the element at that index.
You might also want to define a class that embodies the array of data so that it can take care of the initialization. That way you don't have the initialization occurring multiple times, and you don't have to track if you've initialized anything. (At the very least, defining the pointer as const
prevents its value from being changed to an unexpected value.)
Upvotes: 3
Reputation: 35154
You cannot access the privately declared type from outside the class, even not at file scope of some Cpp-file.
To overcome this, you could declare the type outside the class (but to have it somewhat encapsulated, define it in the CPP-file):
// 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;
}
Upvotes: 0