"nullptr" после инициализации класса с помощью присваивания в C ++ - PullRequest
0 голосов
/ 17 мая 2019

Я создал класс, который хранит тип буфера, его размер и указатель на этот буфер. Намерение состоит в том, чтобы получить доступ к буферу через этот указатель для выполнения всех операций.
Проблема в том, что когда я назначаю экземпляр этого класса другому, например:

    buffer = ExampleUsage(10);  

указатель ломается.

Вот два класса (буфер и использование этого буфера):
Сначала буфер, который я использую в моем примере:

    class ExampleBuffer {
    public:
        ExampleBuffer() :size(0), buffer(0) {}
        ExampleBuffer(size_t size) {
            this->size = size;
            buffer = vector<int>(size);
        }

        void Draw(int index, int val) {
            buffer[index] = val;
        }

        int Get(int index) {
            return buffer[index];
        }
    protected:
        int size;
        vector<int> buffer;
    };

Далее класс, который я использую для доступа к буферу и выполнения операций с ним:

    class ExampleUsage {
    public:
        ExampleUsage() :
            size(0),
            buffer(0), 
            ptr(&buffer) {}

        ExampleUsage(int size) :
            size(size),
            buffer(size), 
            ptr(&buffer) {}

        void Draw(int index, int val) {
            ptr->Draw(index, val);
        }

        int Get(int index) {
            return ptr->Get(index);
        }
    protected:
        int size;
        ExampleBuffer buffer;
        ExampleBuffer* ptr;
    };

Вот программа для демонстрации проблемы.

class SomeClass {
public:
    void Init() {
        buffer = ExampleUsage(10);
    }

    void DoStuff() {
        buffer.Draw(0, 1234);
    }

protected:
    ExampleUsage buffer;
};

int main() {
    SomeClass example;
    example.Init();
    example.DoStuff();
}

Когда он выполняется, он инициализирует ExampleUsage своим конструктором по умолчанию и затем другой экземпляр генерируется в методе Init() из SomeClass и назначается buffer.
Затем вызывается метод DoStuff(), который выполняет метод буфера Draw(), и оттуда указатель должен получить доступ к сохраненному ExampleBuffer, но вместо этого он указывает на nullptr, что приводит к исключению.

Я знаю, что если я уберу строку:

    buffer = ExampleUsage(10);

и вместо этого замените его на что-то вроде:

    buffer.Init(10); //hypothetical method to initialize the class.

это будет работать.

Почему указатель в ExampleUsage не указывает на ExampleBuffer в этой программе?

1 Ответ

2 голосов
/ 17 мая 2019

В этом коде вы копируете вектор и указатель:

buffer = ExampleUsage(10);

В конце дня буферный объект имеет действительную копию вектора плюс указатель на некоторую память, где находится другой векторбыл недавно найден.

class ExampleUsage {
    // ...
    ExampleBuffer buffer; // This is a valid copy of the object
    ExampleBuffer* ptr; // Where does this ptr point after the copying?
};

Это причина для исключения.Другие вопросы, касающиеся кода: почему вы храните размер внешне, если у вас есть эта информация как vector :: size ()?Почему вы храните как вектор, так и указатель (предпочитая использовать указатель)?

Рассмотрим более простое C ++ - идиоматическое решение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...