8

I'm aware that I could use something called std::vector, but I'm afraid it's not possible because of the course restrictions.

I need to make a dynamic extensible array of objects. The array should grow and grow when new objects need to be stored.

Here is the class that the array belongs to:

class TransactionList
{
    private:
        Transaction *trans;
        int amountTransactions;
        Transaction newTrans;

    public:
        TransactionList();
        ~TransactionList();
        void read( istream &is );
        void write( ostream &os );
        void add( Transaction & newTrans ); 
        double totalExpenses();
        double hasPaid( string namnet );
        double isDebted( string namnet );
        //PersonList FixPersons();
 };

The method "void add ( Transaction & newTrans )" is the one I need. And yes, I seriously have to do it pointer-style.

So far this method is totally incomplete and just not even close to functional. I've tried several different ways, but end up with a runtime error or just bollocks result.

void TransactionList::add(Transaction & newTrans)
{
    Transaction* tempArrPtr;

    amountTransactions++;
    trans = new Transaction[amountTransactions]
    trans[amountTransactions - 1] = newTrans;
}

What I want the method to do is to build an array of of Transaction-objects and grow in size while it gets more objects.

I hope I've written about my problem clearly and wish someone could give me a good answer. I tried Googling, but I'm still stuck - otherwise I wouldn't have bothered asking :p

Also if someone could give some pointers about copy constructors, I'd be very thankful. In our course material they pretty much didn't even show what a copy constructor should look like. Just like "You need copy constuctors for deep copying, good luck!"

11
  • 3
    There are some good questions around here about the "rule of three". Read them carefully. Then, read about std::vector. Commented Jun 4, 2011 at 20:25
  • 1
    Here is the one people from Stackoverflow put together for questions like this one. Commented Jun 4, 2011 at 20:25
  • just try copying what you need from STL vector class. Commented Jun 4, 2011 at 20:26
  • 3
    @Gajet: this is not a good idea. Use std::vector, don't copy it. Commented Jun 4, 2011 at 20:26
  • 3
    @Alecandre : after the first piece of code he seid he needs to do it pointer style, I didn't mean to copy it just use the idea vector used. Commented Jun 4, 2011 at 20:28

3 Answers 3

5

You should add a maxTransactions variable, which would indicate the allocated length of your trans* array, and initialize both ammountTransactions and maxTransactions with 0.

Your array would automatically double its size when we reach the limits of trans


void TransactionList::add(Transaction & newTrans)
{
    if(amountTransactions == maxTransactions){ //we've reached the capacity of trans
        //allocate a new array
        Transaction* nuTrans = new Transaction[maxTransactions*2+1];
        //copy the old values of trans into nuTrans
        memcpy(nuTrans, trans, sizeof(Transaction)*maxTransactions);
        //deallocate the old trans array
        delete []trans;
        //set trans to point at your newly allocated array
        trans = nuTrans;
        //update maxTransactions
        maxTransactions = maxTransactions*2+1;
    }

    trans[amountTransactions] = newTrans;
    amountTransactions++;
}


PS. I wrote it directly here, I didn't check it if it compiles as a whole or didn't debug the code. But I present it as an idea you could follow

Edit: Working example @ http://ideone.com/uz1mE

Sign up to request clarification or add additional context in comments.

14 Comments

But I don't see where maxTransaction is assigned with the new capacity after the realloc! btw: maxTransaction*2+1 : why "+1"? (just curious)
Because I stated that we start with both vars =0, and no matter how many times you'd double 0, you'd end up with 0 :). And this way we don't need special initialization code + the doubling of the size of the array is pretty efficient AFAIK
Thanks for your answer matyas! I thought something along those lines also. But the thing is, I have to start with an array that holds just one object and grows one by one as more objects come so it takes as little memory as possible. I really feel this course forces to do things in awkward ways not compliant to good programming methods, but as a student I think I just have to comply :) So no checking of upper limits, me thinks, just plain grow the array by one every time.
Well then you can do maxTransactions+1 instead of maxTransactions*2+1 but that adds a lot of overhead because you copy the whole array every time a new item gets added
@matyas: ah, now I see THAT line :)
|
1

When you add an object and the array is too small you need to create a new one with the correct or larger size, copy the data, delete the old one and replace it with your new one.

Copy constructors are just like ordinary constructors only that they take an object of the same type. Do remember take care of your pointers properly when doing this.

 TransactionList(const TransactionList & o);

4 Comments

Cheers CptRed. But how shouls a copy constructor be implemented? That's something I've been wondering, 'cause they surely didn't have anything about it in the course material.
@Alexandre C.: Duly noted :) Didn't get to reading that yet. Thanks buddy!
@JKase: you're welcome. The C++-faq tag is worth a search, there are some valuable articles for C++ students (stackoverflow.com/questions/tagged/c%2b%2b-faq )
@JKase: have also a look at this one (hard to spot if you never saw the name): stackoverflow.com/questions/3279543/…
0

Now I finally managed to solve this puzzle. Turns out I wasn't paying enough attention to the fact that my Transaction-objects themselves held a dynamic array, so I finally came up with the idea of making an assign function to copy the objects. Thought I'd share my solution just in case any one has to tackle the same problem with the same limited set of tools.

This is how it ended up looking like:

   void TransactionList::add(Transaction & newTrans)

   {
    amountTransactions++;

    cout << "Adding a transaction-object to the array. amountTransactions = " << amountTransactions << endl;
    //Allocate a new array
    Transaction* tempTrans = new Transaction[amountTransactions];
    //Copy the objects with the assign-function
    for (int i = 0; i < amountTransactions - 1; i++)
            tempTrans[i].assign(trans[i]);

    //Delete the old one
    delete[] trans;

    //Set trans to point at the new one
    trans = tempTrans;

    //Add the newcomer object
    trans[amountTransactions - 1].assign(newTrans);
}

And the assign-function looks as follows:

void Transaction::assign(const Transaction & t)
{
    date = t.date;
    type = t.type;
    name = t.name;
    amount = t.amount;
    amountFriends = t.amountFriends;

    cout << "Hello assign " << amountFriends << endl;

    delete [] friends;
    if (amountFriends > 0)
    {
        friends = new string[amountFriends];

        for (int i = 0; i < amountFriends; i++)
            friends[i] = t.friends[i];
    }

    else
        friends = NULL;
}

I based my final solution on matyas' answer, so I owe you one buddy! :) Thanks also to Alexandre C. for good read!

I'm not counting out the possibility there might be some error in the code, but at least it compiles, runs and produces correct result. Feel free to point out if you find something that's not right.

1 Comment

Also here's the complete program for reference: ideone.com/y7luk There seems to be one bug at least. If i do delete[] pers in the destructor for Personlist, the program ends in a runtime error. Turning the assignment in anyway now. Cheers and kudos to everyone who helped! (:

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.