C++ 将向量更改为数组并且必须使用指针-errormessage会说什么?C++;
在我的家庭作业中,我应该将向量从registry类更改为数组,并在BankVector类中定义它。我这样做了,编译器中的错误消息真的是。。。令人困惑我是新来的指针,所以我真的很困惑。错在哪里?或者是错误,哈哈,请帮帮忙C++ 将向量更改为数组并且必须使用指针-errormessage会说什么?C++;,c++,arrays,pointers,vector,C++,Arrays,Pointers,Vector,在我的家庭作业中,我应该将向量从registry类更改为数组,并在BankVector类中定义它。我这样做了,编译器中的错误消息真的是。。。令人困惑我是新来的指针,所以我真的很困惑。错在哪里?或者是错误,哈哈,请帮帮忙 #include <iostream> #include <string> #include <array> #include <fstream> using namespace std; class Bankaccount{
#include <iostream>
#include <string>
#include <array>
#include <fstream>
using namespace std;
class Bankaccount{
private:
string accName;
double balance;
char type;
public:
Bankaccount();
Bankaccount(string name, char credit);
string getName();
double getBalance();
void setBalance(double transferMoney);
char getCredit();
};
Bankaccount::Bankaccount(){
accName = " ";
balance = 0;
type = 'n';
}
Bankaccount::Bankaccount(string name, char credit){
accName = name;
balance = 0;
type = credit;
}
string Bankaccount::getName(){
return accName;
}
double Bankaccount::getBalance(){
return balance;
}
void Bankaccount::setBalance(double transferMoney){
balance += transferMoney;
}
char Bankaccount::getCredit(){
return type;
}
class BankVector {
private:
Bankaccount* entries;
unsigned int usedCapacity;
unsigned int maxCapacity;
public:
BankVector();
~BankVector();
unsigned int size() const;
Bankaccount& at(unsigned int index) const;
void push_back(Bankaccount a);
void erase(unsigned int index);
class IndexError:public exception{
const char* what() const throw(){
return "error: Index out of range";
}
};
};
BankVector::BankVector(){
entries = new Bankaccount;
usedCapacity = 0;
maxCapacity = 0;
}
BankVector::~BankVector(){
delete[] entries;
}
unsigned int BankVector::size() const{
return usedCapacity;
}
Bankaccount& BankVector::at(unsigned int index) const{
if(index > usedCapacity){
throw IndexError();
} else {
return entries[index];
}
}
void BankVector::push_back(Bankaccount a){
if(usedCapacity == maxCapacity){
Bankaccount* tmp = new Bankaccount[maxCapacity + 1];
for(int i = 0; i < maxCapacity; i++){
tmp[i] = entries[i];
}
delete entries;
for(int i = 0; i < maxCapacity; i++){
entries[i] = tmp[i];
}
delete tmp;
entries[maxCapacity] = a;
} else {
entries[usedCapacity + 1] = a;
}
}
void BankVector::erase(unsigned int index){
if(index >= 0 && index < usedCapacity){
for(int i = index; i < usedCapacity - 1; i++){
entries[i] = entries[i + 1];
}
usedCapacity = usedCapacity - 1;
} else{
throw IndexError();
}
}
class Registry{
public:
void addAcc(string name, char isCredit);
void removeAcc(string name);
void transaction(string name, double transMoney);
bool checkDupl(string name);
double checkBalance(string name);
char checkCreditType(string name);
void print();
private:
BankVector accountlist;
int i;
double balance = 0;
char type;
};
void Registry:: addAcc(string name, char isCredit){
Bankaccount newAcc(name, isCredit);
accountlist.push_back(newAcc);
}
void Registry::removeAcc(string name){
for(i = 0; i < accountlist.size(); i++){
if(accountlist.at(i).getName() == name){
accountlist.erase(i);
}
}
}
void Registry::transaction(string name, double transMoney){
for(i = 0; i < accountlist.size(); i++){
if(accountlist.at(i).getName() == name){
accountlist.at(i).setBalance(transMoney);
}
}
}
bool Registry::checkDupl(string name){
for(i = 0; i < accountlist.size(); i++){
if(accountlist.at(i).getName() == name){
return true;
}
}
return false;
}
double Registry::checkBalance(string name){
for(i = 0; i < accountlist.size(); i++){
if(accountlist.at(i).getName() == name){
balance = accountlist.at(i).getBalance();
}
}
return balance;
}
char Registry::checkCreditType(string name){
for(i = 0; i < accountlist.size(); i++){
if(accountlist.at(i).getName() == name){
type = accountlist.at(i).getCredit();
}
}
return type;
}
void Registry::print(){
for(i = 0; i < accountlist.size(); i++){
if(accountlist.at(i).getBalance() >= 0){
cout << accountlist.at(i).getName() << " owns " << accountlist.at(i).getBalance() << " euros" << endl;
} else if(accountlist.at(i).getBalance() < 0){
cout << accountlist.at(i).getName() << " owes " << accountlist.at(i).getBalance() << " euros" << endl;
}
}
}
int main(){
Registry account;
ifstream inFS;
string file, command, fileName;
char creditType;
double moneyVal = 0;
int i = 0;
cout << "Enter the name of the records file: ";
cin >> file;
inFS.open(file);
if(!inFS.is_open()){
cout << "Could not open file " << file;
return 0;
}
while(!inFS.eof()){
i++;
try{
inFS >> command >> fileName;
if(command == "c"){
inFS >> creditType;
if(account.checkDupl(fileName) == true){
throw runtime_error(": account already exists");
} else {
account.addAcc(fileName, creditType);
}
}
if(command == "r"){
if(account.checkDupl(fileName) == false){
throw runtime_error(": account does not exist");
} else if(account.checkDupl(fileName) == true){
if(account.checkBalance(fileName) >= 0){
account.removeAcc(fileName);
} else if(account.checkBalance(fileName) < 0){
throw runtime_error(": account holds negative balance");
}
}
}
if(command == "t"){
inFS >> moneyVal;
if(account.checkDupl(fileName) == true){
if((account.checkBalance(fileName) + moneyVal) >= 0){
account.transaction(fileName, moneyVal);
} else if((account.checkBalance(fileName) + moneyVal) < 0){
if(account.checkCreditType(fileName) == 'y'){
account.transaction(fileName, moneyVal);
} else if(account.checkCreditType(fileName) == 'n'){
throw runtime_error(": account cannot hold negative balance");
}
}
}else{
throw runtime_error(": account does not exist");
}
}
}
catch(runtime_error& excpt){
cout << "error on line " << to_string(i) << excpt.what() << endl;
}
}
cout<< endl;
account.print();
return 0;
}
让我们来分析一下您的
push_back
功能:
Bankaccount* tmp = new Bankaccount[maxCapacity + 1];
for(int i = 0; i < maxCapacity; i++){
tmp[i] = entries[i];
}
好的,所以您不需要旧的数组,但是正如注释部分中已经强调的那样,您必须使用delete[]条目代码>因为它被分配了new[]
for(int i = 0; i < maxCapacity; i++){
entries[i] = tmp[i];
}
不!您不仅应该使用delete[]
,而且不想这样做。刚刚销毁了阵列的最后一个剩余副本。现在你的数据在哪里?拆下这条线
entries[maxCapacity] = a;
是的,它可以正常工作,但您忘记了一件事:maxCapacity
应该在调整阵列大小时增加(或者至少在某个地方)。这一行在技术上是正确的,但在语义上是错误的。您还有另一个变量usedCapacity
,它告诉您在哪里存储数据。理论上,每次调整大小时,您都应该将maxCapacity
增加一个系数,这意味着它通常不会指向下一个空闲插槽。所以你应该这样做:
// Better approach...
entries[usedCapacity] = a;
++usedCapacity;
++maxCapacity; // <- this line should actually go earlier when you resize
//更好的方法。。。
条目[usedCapacity]=a;
++使用容量;
++最大容量;// 您的BankVector
课程中有几个错误。为了清晰起见,这里有一个经过清理的(希望是)正确的版本,内联了成员方法
class BankVector {
Bankaccount* entries = nullptr; // provide default initialisers
unsigned int usedCapacity = 0;
unsigned int maxCapacity = 0;
void grow() // double maxCapacity
{
maxCapacity = maxCapacity? 2*maxCapacity : 1;
Bankaccount*tmp = new Bankaccount[maxCapacity];
for(unsigned int i=0; i!=usedCapacity; ++i)
tmp[i] = entries[i];
delete[] entries;
entries = tmp;
}
public:
BankVector() = default; // use default initialisers
~BankVector()
{ delete[] entries; }
unsigned int size() const
{ return usedCapacity; }
unsigned int capacity() const
{ return maxCapacity; }
Bankaccount const& at(unsigned int index) const // const access
{
if(index >= size())
throw std::range_error("BankVector::at(): index=" +
std::to_string(index) + " >= size()=" + std::to_string(size()));
return entries[index];
}
Bankaccount & at(unsigned int index) // non-const access
{
if(index >= size())
throw std::range_error("BankVector::at(): index=" +
std::to_string(index) + " >= size()=" + std::to_string(size()));
return entries[index];
}
void push_back(Bankaccount const&a)
{
if(size() >= capacity())
grow();
entries[usedCapacity++] = a;
}
void remove(unsigned int index) // fast but not order-preserving
{
if(index < usedCapacity)
entries[index]=entries[--usedCapacity];
}
void erase(unsigned int index) // order-preserving but slow
{
if(index >= size())
throw std::range_error("BankVector::erase(): index=" +
std::to_string(index) + " >= size()=" + std::to_string(size()));
usedCapacity--;
for(unsigned int i=index; i!=usedCapacity; ++i)
entries[i] = entries[i+1];
}
};
classbankvector{
Bankaccount*entries=nullptr;//提供默认初始值设定项
unsigned int usedCapacity=0;
无符号整数最大容量=0;
void grow()//最大容量加倍
{
maxCapacity=maxCapacity?2*maxCapacity:1;
银行账户*tmp=新银行账户[maxCapacity];
for(无符号整数i=0;i!=usedCapacity;++i)
tmp[i]=分录[i];
删除[]项;
条目=tmp;
}
公众:
BankVector()=默认;//使用默认初始值设定项
~BankVector()
{删除[]项;}
无符号整数大小()常量
{返回usedCapacity;}
无符号整数容量()常量
{返回最大容量;}
Bankaccount常量和at(无符号整数索引)常量//常量访问
{
如果(索引>=size())
抛出std::range_错误(“BankVector::at():index=”+
std::to_string(index)+“>=size()=”+std::to_string(size());
返回分录[索引];
}
Bankaccount&at(无符号整数索引)//非常量访问
{
如果(索引>=size())
抛出std::range_错误(“BankVector::at():index=”+
std::to_string(index)+“>=size()=”+std::to_string(size());
返回分录[索引];
}
无效回推(银行账户const&a)
{
如果(大小()>=容量())
增长();
条目[usedCapacity++]=a;
}
void remove(unsigned int index)//快速但不保留顺序
{
如果(索引<使用容量)
条目[索引]=条目[--usedCapacity];
}
void erase(unsigned int index)//保留顺序但速度较慢
{
如果(索引>=size())
抛出std::range_错误(“BankVector::erase():index=”+
std::to_string(index)+“>=size()=”+std::to_string(size());
使用容量--;
for(无符号整数i=index;i!=usedCapacity;++i)
分录[i]=分录[i+1];
}
};
它表示您尝试删除(或删除[]
)以前未由新建(或新建[]
)分配的指针,或者可能是删除两次。只需查看您的代码。。。分配给new
的指针必须使用delete
解除分配,分配给new[]
的指针必须使用delete[]
解除分配。没有混合和匹配。您应该在BankVector
的默认构造函数中了解,您使用new
分配内存,但析构函数使用delete[]
取消分配内存。此外,由于没有要管理的数据,因此不需要在默认构造函数中分配内存。(maxCapacity==usedCapacity==0
)顺便说一句。您应该使用构造函数初始化列表来初始化成员。这些赋值应该让您创建自己的向量类,以便您了解如何组合向量类的基本知识。此答案中存在语法和逻辑错误。一般来说,我认为最好是解释OP的错误并让他们纠正错误,而不是简单地为他们重写代码。erase()
wt。。见鬼?如果(size()>capacity())
如果这是真的,那么向量实现就被破坏了。我们要花更多的时间来更正这个答案,而不是更正原始代码。我投了反对票,因为我觉得答案没有用。它既不能回答问题,也不能教会OP任何东西。尽管您目前正在努力修复代码,但它仍然无法工作,甚至无法编译。最后,它添加了最新语言版本的语法,这些语法在原始代码中并不明显。所有这些只会让OP感到困惑,而不是教育他们。
entries[maxCapacity] = a;
// Better approach...
entries[usedCapacity] = a;
++usedCapacity;
++maxCapacity; // <- this line should actually go earlier when you resize
class BankVector {
Bankaccount* entries = nullptr; // provide default initialisers
unsigned int usedCapacity = 0;
unsigned int maxCapacity = 0;
void grow() // double maxCapacity
{
maxCapacity = maxCapacity? 2*maxCapacity : 1;
Bankaccount*tmp = new Bankaccount[maxCapacity];
for(unsigned int i=0; i!=usedCapacity; ++i)
tmp[i] = entries[i];
delete[] entries;
entries = tmp;
}
public:
BankVector() = default; // use default initialisers
~BankVector()
{ delete[] entries; }
unsigned int size() const
{ return usedCapacity; }
unsigned int capacity() const
{ return maxCapacity; }
Bankaccount const& at(unsigned int index) const // const access
{
if(index >= size())
throw std::range_error("BankVector::at(): index=" +
std::to_string(index) + " >= size()=" + std::to_string(size()));
return entries[index];
}
Bankaccount & at(unsigned int index) // non-const access
{
if(index >= size())
throw std::range_error("BankVector::at(): index=" +
std::to_string(index) + " >= size()=" + std::to_string(size()));
return entries[index];
}
void push_back(Bankaccount const&a)
{
if(size() >= capacity())
grow();
entries[usedCapacity++] = a;
}
void remove(unsigned int index) // fast but not order-preserving
{
if(index < usedCapacity)
entries[index]=entries[--usedCapacity];
}
void erase(unsigned int index) // order-preserving but slow
{
if(index >= size())
throw std::range_error("BankVector::erase(): index=" +
std::to_string(index) + " >= size()=" + std::to_string(size()));
usedCapacity--;
for(unsigned int i=index; i!=usedCapacity; ++i)
entries[i] = entries[i+1];
}
};