1

I am new to C++ and just learned about classes in a course I watched, I'm trying to make a little blockchain project and I'm having trouble with constructors. I have a class, Transaction whose constructor takes in three parameters, and am trying to make that a parameter of another class, Block's constructor. Here is the definition for the constructor of Transaction,

Transaction::Transaction(std::string fromAddress, std::string toAddress, uint32_t amount)
{
    this->fromAddress = fromAddress;
    this->toAddress = toAddress;
    this->amount = amount;
}

And I'm trying to use the Transaction class as a parameter for the Block class

Block::Block(time_t timestamp, Transaction transaction(std::string fromAddress, std::string 
toAddress, uint32_t amount), std::string prevHash)
{
    this->timestamp = time(nullptr);
    this->transactionSet(std::string fromAddress, std::string toAddress, uint32_t amount) = 
transaction(std::string fromAddress, std::string toAddress, uint32_t amount);
    this->prevHash = "";
}

But I get tons of errors for doing this, I tried a ton of different ways but I don't know how to implement it, so how do you use a parameterized object as a parameter for another class?

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • 1
    `Block::Block(time_t timestamp, Transaction transaction, std::string prevHash)`? No need to repeat the constructor. You simply want an instance of `Transaction` and don't need care how it was created. – Lukas-T Jun 18 '21 at 07:09
  • 1
    Also `transactionSet = transaction;` – Some programmer dude Jun 18 '21 at 07:11
  • 1
    I also recommend you do some research about *constructor initializer lists*. – Some programmer dude Jun 18 '21 at 07:13
  • And I recommend you invest in [some good books](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) to read. Unless you take an online course where you pay for it, online video tutorials tend to be rather shallow and narrow. Reading books and taking actual classes (or pay for online courses) is a much better way to learn programming. – Some programmer dude Jun 18 '21 at 07:15
  • 1
    Do you have any questions or comments on the suggested solution below? – rawrex Jun 18 '21 at 07:35

1 Answers1

2

An object construction happens before you pass it as a parameter to a function or method. And the parameters are set during construction. When a method accepts an object as argument, it does not matter for the method if the object has a parameterized constructor or not. According to how you have defined your constructor, you have to first create a Transaction object at the calling site and then pass it to the method.

Block::Block(time_t timestamp, Transaction transaction, std::string prevHash)
{
    this->timestamp = time(nullptr);
    this->transactionSet = transaction;
    this->prevHash = prevHash;
}

An object of Block will be created as follows:

time_t tm;
time(&tm);
Block block(tm, Transaction("X", "Y", 100), "YourHash");

or

...
Transaction t("X", "Y", 100);
Block block(tm, t, "YourHash");

As it can be noticed, the constructor has nothing to do with the parameterized constructor of Transaction.


However, there is another way by which you can delegate the creation of a new Transaction to Block's constructor:

Block::Block(time_t timestamp, std::string fromAddress, std::string toAddress, uint32_t amount, std::string prevHash)
{
    this->timestamp = timestamp;
    this->transactionSet = Transaction(fromAddress, toAddress, amount);
    this->prevHash = prevHash;
}

Here, you are not passing in a new transaction, but telling Block's constructor: here are the parameters of Transaction's constructor, use them to create a new Transaction:

Block block(tm, "X", "Y", 100, "YourHash");

Member Initializer Lists

Also, has Some programmer dude has mentioned, your constructor can be written more succinctly using a member initializer list:

Block::Block(time_t ts, Transaction t, std::string previousHash) 
: timestamp(ts), transactionSet(t), prevHash(previousHash)
{
}

Initializer lists are intended to take the member-wise initialization out of the constructor so that the body of your constructor remains cleaner. As you can notice, the constructor body is now empty. The syntax for initializer lists is:

ClassName(
    type_1 parameter_name_1, 
    type_2 parameter_name_2, 
    ... type_n parameter_name_n) 
    : member_name_1(parameter_name_1),
      member_name_2(parameter_name_2),
  ... member_name_n(parameter_name_n)
{
    // constructor body
}
Amal K
  • 4,359
  • 2
  • 22
  • 44