Статический член типа приватный член данных - PullRequest
0 голосов
/ 06 февраля 2019

В приведенном ниже коде класс 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;"не работает

PS Это отличается от других вопросов в StackOverflow, поскольку тип статического члена данных имеет структуру, определенную как закрытый член.Любая помощь высоко ценится.

Ответы [ 2 ]

0 голосов
/ 06 февраля 2019

Для определения переменной используйте:

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 предотвращает изменение его значения на неожиданное значение.)

0 голосов
/ 06 февраля 2019

Вы не можете получить доступ к объявленному в частном порядке типу из-за пределов класса, даже за пределами области видимости какого-либо 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;
}
...