ScoderNH
ScoderNH

Reputation: 11

C++ Create Object Array without default constructor

I get an error when dynamically creating an array of a (transaction) object. The error output says:"no matching function for call to 'Transaction::Transaction()' This is part of an assignment and we are not allowed to use a default constructor. From what I gather an array automatically assigns values to each of its indexed address when it's created and as no default constructor is made for Transaction, it cannot do this without values. Please help me see what I could do to fix this error.

class Transaction
{
private:
  int id;
  float amount;
  string fromAddress, toAddress, signature;
  bool confirmed, removeFromPool;
  static int numTransactions;


public:
  Transaction(string in_fA, string in_tA,string in_sign,float in_amount);
  Transaction(Transaction &obj);
  int getId() const;
}
//---------------------

class Block
{
private:
  int id, txCount;
  const int MAX_TX=5;
  Transaction** txList;
  string blockHash, prevBlockHash, minerName;
  bool confirmed;

public:
  Block(int id,string prevH,string name);
  }
//------------------
// block.cpp
Block::Block(int i, string prevH, string name)
{
*txList = new Transaction[MAX_TX];
}

Upvotes: 1

Views: 6016

Answers (3)

HolyBlackCat
HolyBlackCat

Reputation: 96286

If you insist on using a plain dynamic array, you could do this:

*txList = new Transaction[MAX_TX]{{"1", "2", "3", 4},
                                  // 3 more
                                  {"5", "6", "7", 8}};

But instead you could declare your constructor as:

Transaction(string in_fA = "a", string in_tA = "b", string in_sign = "c", float in_amount = 42);

And thus attempt to dodge the silly 'no default ctor' requirement.

Upvotes: 1

WindyFields
WindyFields

Reputation: 2875

If this is your "assignment" and you are not allowed to use default constructors I assume you are expected to use one of these:

  • malloc
  • std::vector which uses malloc under the hood

In the first option memory allocation looks like this:

Transaction* transactionsList = (Transaction*) malloc(size * sizeof(Transaction));

Edit: don't forget that after malloc you use free and not delete to free the memory.

I have to note, that the usage of malloc is usually discouraged in favor of new in C++. The point of new is to merge together 2 phases: memory allocation and memory initialization (+ the pointer type conversation is done for you). However, everything you need is to allocate a chunk of memory, you may consider malloc. Anyway, take a look at this.

The second option which Jarod42 and Frank noted:

std::vector<Transaction> transactionsList(size, *default_value*);

and you get the vector of size elements, each is initialized to the default value you specified.

If you are allowed to define a move Transaction(Transaction&& obj) = default; or a copy constructor Transaction(const Transaction& obj) { ... }, you also can also reserve memory:

std::vector<Transaction> transactionsList;
transactionsList.reserve(size);

and then add a new element with emplace_back() or push_back().

Upvotes: 0

user4442671
user4442671

Reputation:

Using a std::vector is the easiest (and best) way to deal with this:

class Block {
public:
  Block()
    : txList(MAX_TX, Transaction("a", "b", "C", 0.0f)) {}

private:
  std::vector<Transaction> txList;
};

Upvotes: 0

Related Questions