调整动态分配的指针数组的大小(Copy Constructor不工作?)

时间:2017-10-04 21:05:07

标签: c++ arrays dynamic

在我问我的问题之前,让我抛弃我的计划的限制:
  - 不允许使用向量(这是作业)

我正在测试我的课程,以确保他们按照我的意图行事。我正在尝试增加动态分配的指针数组的大小。在调试时,我发现当我将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;
}

1 个答案:

答案 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并在这种情况下执行此代码。您可能希望有一些减少容量的策略,但可以省略。