在我问我的问题之前,让我抛弃我的计划的限制:
- 不允许使用向量(这是作业)
我正在测试我的课程,以确保他们按照我的意图行事。我正在尝试增加动态分配的指针数组的大小。在调试时,我发现当我将pTemp [i]设置为pTransactions [i]时,没有使用复制构造函数;当pTransactions [i]被删除几行之后,应该在pTemp [i]中的数据消失了(参见下面的代码)。有什么明显的东西我不见了吗?
以下是我的问题的相关文件:(如果您需要更多代码,请告诉我)
此外,我的代码中缺少颜色道歉。这是我的第一篇文章,我并不完全习惯这里的格式。编辑:开个玩笑,我现在看到它只是稍后放入颜色......
(类Account的部分代码 - pTransactions是动态分配的指针数组)
void Account::createNewTransaction(Transaction* newTrans) {
if (numberOfTransactions > 0) {
//Create temp pointer
Transaction **pTemp = new Transaction*[++numberOfTransactions];
//Copy array to temp
if (*pTransactions) {
for (int i = 0; i < numberOfTransactions - 1; i++) {
Transaction *tempTrans = pTransactions[i];
pTemp[i] = tempTrans;
}
for (int i = 0; i < numberOfTransactions - 1; i++) {
delete pTransactions[i];
}
delete[] pTransactions;
}
//Recreate array
pTransactions = new Transaction*[numberOfTransactions];
for (int i = 0; i < numberOfTransactions; i++) {
pTransactions[i] = pTemp[i];
}
}
else {
numberOfTransactions++;
pTransactions = new Transaction*[numberOfTransactions];
}
pTransactions[numberOfTransactions - 1] = newTrans;
double oldBalance = balance; //Variable to hold original balance
//Complete correct type of transaction
if (newTrans == dynamic_cast<Deposit*>(newTrans))
balance = static_cast<Deposit*>(newTrans)->makeDeposit(balance);
else if (newTrans == dynamic_cast<Withdraw*>(newTrans))
balance = static_cast<Withdraw*>(newTrans)->makeWithdrawal(balance);
else
balance = static_cast<Check*>(newTrans)->makeCheck(balance);
//If balance equals oldBalance -- no transaction actually occurred
if (balance == oldBalance) {
numberOfTransactions--;
}
}
Transaction.ccp - Transaction是一个抽象类
#include "Transaction.h"
Transaction::Transaction()
{
id = ++transactionTracker;
}
Transaction::~Transaction()
{
}
int Transaction::getTransactionTracker()
{
return transactionTracker;
}
//Mutator Functions
void Transaction::setId(int newId) {
id = newId;
}
void Transaction::setAmount(double amt) {
amount = amt;
}
//Other Functions
void Transaction::cancelTransaction() {
transactionTracker--;
}
Deposit.cpp - 存款是交易的派生类
#include "Deposit.h"
#include <iostream>
//Constructor
Deposit::Deposit(double amt)
{
setAmount(amt);
}
//Copy Constructor
Deposit::Deposit(const Deposit &obj)
{
id = obj.id;
amount = obj.amount;
}
//Deconstructor
Deposit::~Deposit()
{
}
//Functions
double Deposit::makeDeposit(double balance) {
return balance + amount;
}
//Overloaded function (from Transaction)
void Deposit::toString() {
cout << "-------------------------------------\n";
cout << "Transaction #" << id << endl;
cout << "Deposited $" << amount << endl;
cout << "-------------------------------------\n";
}
//Overloaded = operator
const Deposit Deposit::operator=(const Deposit &obj)
{
id = obj.id;
amount = obj.amount;
return *this;
}
Withdraw.cpp - Withdraw是一个派生类别的交易
#include "Withdraw.h"
#include<iostream>
//Constructor
Withdraw::Withdraw(double amt)
{
setAmount(amt);
}
//Copy Constructor
Withdraw::Withdraw(const Withdraw &obj)
{
id = obj.id;
amount = obj.amount;
}
//Destructor
Withdraw::~Withdraw()
{
}
//Functions
double Withdraw::makeWithdrawal(double balance) {
if (balance > amount) {
return balance - amount;
}
else {
cancelTransaction();
cout << "Amount exceeds balance. Request denied.\n";
return balance;
}
}
Overloaded function (from Transaction)
void Withdraw::toString() {
cout << "-------------------------------------\n";
cout << "Transaction #" << id << endl;
cout << "Withdrew $" << amount << endl;
cout << "-------------------------------------\n";
}
//Overloaded = operator
const Withdraw Withdraw::operator=(const Withdraw &obj)
{
id = obj.id;
amount = obj.id;
return *this;
}
Checks.cpp - Checks是一个派生的交易类
#include "Check.h"
#include<iostream>
//Constructor
Check::Check(double amt, string name)
{
setAmount(amt);
setName(name);
checkNumber = ++numberedChecks;
}
//Copy Constructor
Check::Check(const Check &obj)
{
id = obj.id;
amount = obj.amount;
checkNumber = obj.checkNumber;
name = obj.name;
}
//Deconstructor
heck::~Check()
{
}
//Mutator Function
void Check::setCheckNumber(int number) {
checkNumber = number;
}
void Check::setName(string newName) {
name = newName;
}
//Other Functions
double Check::makeCheck(double balance)
{
if (balance > amount)
return balance - amount;
else {
cancelTransaction();
cout << "If that check were to go through, you would have an overdraft. Request denied.\n";
return balance;
}
}
//Overloaded Function (from Transaction)
void Check::toString() {
cout << "-------------------------------------\n";
cout << "Transition #" << id << endl;
cout << "Check #" << checkNumber << endl;
cout << "For the amount of $" << amount << endl;
cout << "Made out to " << name << endl << endl;
cout << "-------------------------------------\n";
}
//Overloaded = operator
const Check Check::operator= (const Check &obj)
{
id = obj.id;
amount = obj.amount;
checkNumber = obj.checkNumber;
name = obj.name;
return *this;
}
答案 0 :(得分:0)
考虑以下代码:
Something *a = new Something;
Something *b = a;
delete a;
在此代码行中,不会调用Something
的复制构造函数,只需将一个指针指向另一个,不复制对象。当你破坏a
指向的对象时,你不能再使用b
,因为它与a
是同一个指针,即它指向同一个内存。您的代码中存在以下问题:
if (*pTransactions) {
for (int i = 0; i < numberOfTransactions - 1; i++) {
Transaction *tempTrans = pTransactions[i];
pTemp[i] = tempTrans;
}
for (int i = 0; i < numberOfTransactions - 1; i++) {
delete pTransactions[i];
}
delete[] pTransactions;
}
目前还不清楚为什么你期望复制ctor被调用,更重要的是为什么你需要它被调用,只是不要破坏对象,只有存储指针的内存。
这不是错误,但创建临时数组,复制所有内容然后再次复制到新数组是非常无效的。并且将数组大小增加一个也不是一个好主意。
什么是更好的方法?
只需将当前指针移动到temp,然后分配新指针并复制指针。记住将一个指针复制到另一个是简单的操作(比如将一个int
分配给另一个)但复制数组不是:
Transaction **pTemp = pTRansactions;
pTransactions = new Transaction*[capacity];
if( pTemp ) {
// copy existing transactions from pTemp to pTransactions
delete[] pTemp;
}
// done
并且您应该有另一个成员capacity
并在大小到达时将其增加delta并在这种情况下执行此代码。您可能希望有一些减少容量的策略,但可以省略。