Переменные классов удаляются автоматически после выхода из области действия. Как я могу предотвратить это? - PullRequest
0 голосов
/ 27 апреля 2019

У меня возникла проблема при вызове функции классов (класса A) из другой функции классов (класса B), когда переменные из класса, который я пытаюсь вызвать (класс A), которые созданы в этом классе, удаляются после функция завершается и возвращается к функции, из которой я вызываю (класс C). Что происходит и как мне это исправить?

Я пытался использовать указатели на этот класс и динамически размещать весь класс, но переменные по-прежнему удаляются.


#include <iostream>
#include <vector>
#include <string>
#include <ctime>
using namespace std;

class A {

private:

    vector<string> vectorA;
    string stringA[5] = { "1", "2", "3", "4", "5" };
    string stringB[5] = { "6", "7", "8", "9" };

public:


    string generaterandnum() {
        int num1 = NULL;
        num1 = rand() % vectorA.size();
        string card = vectorA[num1];
        vectorA.erase(vectorA.begin() + num1);
        return card;
    }


    void buildvectorA()
    {
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 5; j++) {
                vectorA.push_back(stringA[j] + stringB[i]);
            }
        }
        return;
    }
};

class B {
private:
    vector<string>  vectorB;
    vector<string>  vectorC;

    A aobject;

public:

    void buildvectorBandC() {
        for (int i = 0; i < 5; i++) {
            vectorB.push_back(aobject.generaterandnum());
        }
        for (int i = 0; i < 5; i++) {
            vectorC.push_back(aobject.generaterandnum());
        }
    }

    void displayvector() {
        cout << "Vector: ";
        for (size_t i = 0; i < vectorB.size(); i++) {
            cout << "[" << vectorB[i] << "] (" << i << ") ";
        }
        cout << endl;
    }
};

    class C {
        friend int main();
        void programrun(int option) {
            A* a = new A;
            a->buildvectorA();
            B* b = new B;

            if (option == 0) {
                cout << "Here is the vector that just has been constructed" << endl;
                b->buildvectorBandC();
                while (true) {
                    b->displayvector();

                }
            }
        }
    };

    int main() {
        srand((unsigned int)time(NULL));
        cout << "Hello" << endl;
        cout << "Enter (R) to run the program." << endl;
        char input;
        while (true) {
            cin >> input;
            input = toupper(input);
            if (input == 'R') {
                C cobject;
                cobject.programrun(0);
                return false;
            }
            else {
                cout << "Invalid input" << endl;
            }
        }
    }

Я ожидал построить вектор B и C со случайно сгенерированными числами, которые выбирают переменные из вектора A. Но то, что я получил, было, когда он получал функцию generaterandnum (), он отображал сообщение об ошибке «Необработанное исключение» в 0x00F1C77F в Project1.exe: 0xC0000094: целочисленное деление на ноль. потому что vectorA имеет размер 0, потому что он был удален после того, как программа покинула область действия этого класса.

1 Ответ

1 голос
/ 27 апреля 2019

Члены класса живут столько же, сколько и объекты вашего класса. Проблема не в времени жизни объекта, а в том факте, что B::aobject никогда не вызывал buildvectorA, поэтому vectorA пусто, поэтому vectorA.size() == 0. Затем вы пытаетесь вычислить rand() % vectorA.size(), и (целочисленное) деление на 0 является довольно плохой идеей.

Вы можете создать конструктор для A и вызвать generaterandnum, чтобы убедиться, что он всегда корректен:

class A {

private:
    vector<string> vectorA;
    string stringA[5] = { "1", "2", "3", "4", "5" };
    string stringB[5] = { "6", "7", "8", "9" };

    void buildvectorA()
    {
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 5; j++) {
                vectorA.push_back(stringA[j] + stringB[i]);
            }
        }
    }

public:
    A() {
        buildvectorA();
    }

    string generaterandnum() {
        int num1 = NULL;
        num1 = rand() % vectorA.size();
        string card = vectorA[num1];
        vectorA.erase(vectorA.begin() + num1);
        return card;
    }
};

Обратите внимание, что buildvectorA теперь является закрытым методом. Мы не хотим, чтобы кто-то извне звонил, потому что им все равно, как генерируются случайные числа. Они просто хотят получить эти случайные числа.

Это также означает, что вашему классу C не нужно вызывать buildvectorA, и фактически ему даже не нужно иметь какой-либо объект A.

...