我正在开展一个项目,在那里我可以创建银行账户并能够存款和取款。我要创建两个银行帐户和两个人 - 一个是堆栈,另一个是堆。我应该每次存入和取出两次,并获取余额打印名称和ID和帐号。目前,我得到了我认为是站点故障,读取或写入受保护的内存。我已经留下了我认为错误所在的地方的评论。我将不胜感激任何帮助。感谢。
#include <iostream>
#include <string>
using namespace std;
class BankAccount {
private:
double *balance;
int *accountNumber;
public:
BankAccount(){//default constructor
*balance = 0.0;/***This is where is says the Access violation lies*/
*accountNumber = 0;
}
BankAccount(double bal, int acctNum){//constructor
balance = new double(bal);
accountNumber = new int(acctNum);
}
~BankAccount() {delete balance; delete accountNumber;}
void Deposit(double amt) {
*balance = *balance + amt;
}
virtual double GetBalance() {
return *balance;
}
virtual double GetAccountNumber() {
return *accountNumber;
}
virtual double Withdraw(double amt) {
*balance = *balance - amt;
return *balance;
}
};
class Person {
string *name;
int *ID;
public:
Person(){//default constructor
*name = "name not yet defined";
*ID = 0;
}
Person(string nameIn, int idIn){//constructor
name = new string(nameIn);
ID = new int(idIn);
}
virtual int GetID() {
return *ID;
}
virtual string GetName() {
return *name;
}
};
class NamedBankAccount: public BankAccount {
private:
Person *owner;
public:
NamedBankAccount(){
}
NamedBankAccount(Person *p): owner(p){/***This is where is says the Access violation lies*/
p = new Person();
}
~NamedBankAccount(){delete owner;}
Person getPerson() {
return *owner;
}
};
int main() {
Person *q = new Person("Joe", 54321);
cout << q->GetName() << endl;
cout << q->GetID() << endl;
NamedBankAccount nba1;/***This is where is says the Access violation lies*/
NamedBankAccount *nba2 = new NamedBankAccount(q);
nba1.Deposit(50);
nba1.Deposit(50);
nba1.Withdraw(25);
cout << nba1.GetBalance() <<endl;//should print 75
nba2->Deposit(60);
nba2->Deposit(60);
nba2->Withdraw(20);
cout << nba2->GetBalance() << endl;//should print 100
getchar();
return 0;
}
答案 0 :(得分:4)
不要在这里使用指针。让这些字符串和整数成为成员变量。对于特定问题 - 在默认构造函数中赋值之前没有分配任何内存。
做类似的事情:
class BankAccount {
private:
double balance;
int accountNumber;
public:
BankAccount() :
balance( 0.0 ),
accountNumber( 0 ) {}
// ...
关于代码的更多要点:
virtual
析构函数,因此可以通过指向base的指针正确销毁派生类的实例virtual
的所有成员函数,只要那些希望派生类重写的那些const
,以便您可以从const
实例答案 1 :(得分:0)
“不使用指针”有点强,但尼古拉的意思是成员变量不应该指向基类型而只是那些类型
即。在BankAccount
中,balance
应该只是double
而不是double*
对其他人来说是明智的
或让BankAccount()
调用BankAccount(0.0, 0)
,因为它会为Person()
分配正确的字段,但出乎意料的是,这不符合我在C ++中的想法,因为Karl Knechtel评论< / p>
答案 2 :(得分:0)
您正在取消引用未初始化的指针,如果您更改其位置,它仍会执行相同的操作。
你看,c ++(和c)使用指针作为内存的地址,如果你没有初始化,那么它们将指向内存中的任何地方,因此解除引用将导致访问冲突(可能是因为你不知道是你的指针指向)。
正确的方法是:
BankAccount(){//default constructor
balance = new double; // Initialize pointer (make it points to a valid memory address)
*balance = 0.0; // Give a value to the variable where balance is pointing
accountNumber = new int; // Initialize pointer (make it points to a valid memory address)
*accountNumber = 0; // Give a value to the variable where balance is pointing
}
或者,如果你想在后面分配内存:
BankAccount(){//default constructor
balance = 0; // Make it point to address 0 (conventional value meaning it is uninitialized)
accountNumber = 0; // Make it point to address 0 (conventional value meaning it is uninitialized)
}
当然,如上所述,在您的情况下,最好使用普通变量而不是指针。你应该在使用它们之前阅读更多有关指针的内容,它们可能很痛苦(我想我代表99.999%的C和C ++程序员在这里发言,我们都在那里)。