C ++: программа падает, когда я пытаюсь получить доступ к закрытой строковой переменной класса. Почему это так, и что я могу сделать, чтобы это исправить? - PullRequest
0 голосов
/ 02 апреля 2020

Я пишу программу для банковского счета, которая предоставляет пользователю систему меню, которая позволяет ему выбирать между 4 вариантами: A) Добавить клиента, B) Распечатать все данные клиента, C) Обновить данные клиента, и Г) Выйти из программы. Каждый вариант выполняет отдельные задачи. Опция, на которой я сосредоточен в этом вопросе, - это опция A .

. Опция A должна создать новый объект банковского счета и попросить пользователя ввести имя владельца счета, начальный депозит для учетной записи (сколько денег начать с новой учетной записи) и процентная ставка. Затем необходимо установить для этих значений правильные личные значения в классе bankAccount для любого данного объекта.

Код для main. cpp перед вариантом B (после этого кода немного больше, отсюда и отсутствие обратных скобок в конце, но я хочу попытаться сделать это более кратким):

#include <iostream>
#include <string>
#include <cstdlib>
#include "header.h"
#include "implementation.cpp"

using namespace std;

int main()
{
    //array of bankAccount class objects (up to 20)
    bankAccount account[20];
    string menuInput = "";           //used for menu loop input
    string accNameInput = "";        //used for account customer name user input
    float depositInput = 0;   //used for initial deposit input
    float interestInput = 0;  //used for initial interest input
   // int customerCount = 0;    //used to compare to static int to determine # of customers in memory

    int static i = 0;

    //while loop keeps user in the menu until they choose to exit program

    while (true)
    {

    cout << endl << "Enter a letter option below: "
        << endl << endl << "A: Add a customer" << endl << "B: Print all customer data available"
        << endl << "C: Update customer data" << endl << "D: End program" << endl << endl;

    cin >> menuInput;

 //Option A: Add a customer
 if (menuInput == "A" || menuInput == "a")
 {
     //checking for max customer limit
    if (i > 19)
    {
        cout << endl << "Cannot add customer; Max customer capacity reached." << endl;
    }
    else //
     {
        ///Creates a new customer account and asks for new customer name,
        ///initial deposit amount, & interest
       cout << endl << "Bank account #" << (i + 1) << " created." << endl;
       bankAccount account[i];     //new bank account object created

        //time to set the name for our new customer...
       cout << endl << "Enter customer name for account #" << (i + 1) << ": " << endl;
       cin >> accNameInput;


       //setting initial deposit amount
       cout << endl << "Enter initial deposit amount for account #" << (i + 1) << ": " << endl;
       cin >> depositInput;


       //setting initial interest rate
       cout << endl << "Enter interest rate (without % sign): " << endl;
       cin >> interestInput;


 account[i].setInterestRate(interestInput);
 account[i].setBalance(depositInput);
 account[i].setAccountHolderName(accNameInput);


        //increments the account number counter
        i++;
     }
 }

Проблема сохраняется с setAccountHolderName (), найденным в последней строке здесь:

account[i].setInterestRate(interestInput);
account[i].setBalance(depositInput);
account[i].setAccountHolderName(accNameInput);

Когда я вызываю функции класса setInterestRate и setBalance, чтобы установить входные значения для соответствующих им переменных частного класса, программа работает как обычно и возвращает пользователя в главное меню, как и должно быть. Но вызов setAccountHolderName приводит к сбою программы и возвращает это значение: -1073741819 (0xC0000005).

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

header.h (включает функции get / set accountHolderName):

///Name of file: header.h
#ifndef HEADER_H_INCLUDED
#define HEADER_H_INCLUDED
#include <iostream>
#include <string>

using namespace std;

class bankAccount
{
    //private data values
    string accountHolderName;
    int accountNumber;
    //static int accCounter;  //keeps track of account numbers
    float balance;
    float interestRate;

public:

    //Default constructor
    bankAccount();

    ///Getters/setters for all private member variables
    //accountNumber
    int getAccountNumber();
    void setAccountNumber(int accNum);

    //accountHolderName
    string getAccountHolderName();
    void setAccountHolderName(string accName);

реализация. cpp (включает реализацию accountHolderName):

///Name of file: implementation.cpp
#include <iostream>
#include <string>
#include "header.h"

using namespace std;

//static int definition (guess you have to define static members here?)
//int bankAccount::accCounter;

//Default constructor
bankAccount::bankAccount()
{
    accountHolderName = "";
    accountNumber = 0;
   // accCounter = 0;
    balance = 0;
    interestRate = 0;
}

    ///Getters/setters for all private member variables
    //accountNumber
int bankAccount::getAccountNumber()
{
    return accountNumber;
}
void bankAccount::setAccountNumber(int accNum)
{
    accountNumber = accNum;
}

    //accountHolderName
string bankAccount::getAccountHolderName()
{
    return accountHolderName;
}
void bankAccount::setAccountHolderName(string accName)
{
    accountHolderName = accName;
}

It Похоже, что возиться с кодом определенным образом (например, полное удаление кода, который следует за кодом варианта А, комментирование accountHolderName = ""; в конструкторе по умолчанию и т. д. c.) временно позволит account[i].setAccountHolderName(accNameInput); функционировать без сбоя программа, но это невероятно противоречиво и смущает меня еще больше. Я не уверен, что проблема связана с памятью или что. Я также пытался использовать cout, чтобы увидеть, сохраняется ли входная переменная accNameInput из main. cpp, к которой она относится.

Извините, если это просто слишком много кода или объяснения; это мой первый пост, и я просто хотел предоставить хороший кусок своего кода, чтобы вы могли видеть весь масштаб вещей. Все, что я пытаюсь сделать здесь, - это получить доступ к закрытой строковой переменной класса bankAccount, accountHolderName, и сохранить вводимые пользователем данные в каждый новый объект .

Я пытался устранить эту проблему в Интернете, но не смог Кажется, я не нашел ничего похожего. Я не уверен, что мне не хватает; любая помощь или руководство будут очень благодарны.

1 Ответ

1 голос
/ 02 апреля 2020

Технически, эта строка:

bankAccount account[i];     //new bank account object created

Не разрешена в C ++, но некоторые компиляторы (g ++) допускают это как расширение, поскольку формально поддерживают массивы переменных стека с помощью компилятора C.

Кроме того, это объявление переопределяет переменную с тем же именем, объявленной в более высоком диапазоне

Но затем вы попадаете в следующие строки:

account[i].setInterestRate(interestInput);
account[i].setBalance(depositInput);
account[i].setAccountHolderName(accNameInput);

Но действительные индексы диапазон массива для 0..i-1 Таким образом, вы уже находитесь в неопределенном поведении с индексом массива вне границ.

Я подозреваю, что вы действительно имели в виду следующее:

bankAccount newAccount;     //new bank account object created

...

newAccount.setInterestRate(interestInput);
newAccount.setBalance(depositInput);
newAccount.setAccountHolderName(accNameInput);

account[i] = newAccount;
i++;
...