1

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];
}
4
  • 4
    Use std::vector and push_back/emplace_back. Commented Aug 14, 2017 at 18:17
  • If you want to still use pointers and want to initialize all objects to the same value, then you can do e.g. *txList = new Transaction[MAX_TX](parameters_passed_to_all_constructors) Commented Aug 14, 2017 at 18:20
  • Define default constructor? Commented Aug 14, 2017 at 18:20
  • BTW, currently, txList is not initialized, you probably want something like txList = new Transaction*[MAX_TX]; for (int i = 0; i != MAX_TX; ++i) { txList[i] = new Transaction(/*parameters*/); } Commented Aug 14, 2017 at 18:27

3 Answers 3

1

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.

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

Comments

0

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;
};

Comments

0

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().

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.