arjacsoh
arjacsoh

Reputation: 9232

Reference as class member initialization

I want to initialize a property of a class that holds a reference to another class by passing such a reference as a parameter to the constructor. However I receive an error:

“'TaxSquare::bank' must be initialized in constructor base/member initializer list”. What is wrong in the following code of the classes?

#ifndef TAXSQUARE_H
#define TAXSQUARE_H
#include "Square.h"

class Bank;

class TaxSquare : public Square
{
    public:
      TaxSquare(int, int, Bank&);
      virtual void process();

    private:
      int taxAmount;
      Bank& bank;

};
#endif
#include <iostream>
#include "TaxSquare.h"
#include "Player.h"
#include "Bank.h"
using namespace std;

TaxSquare::TaxSquare(int anID, int amount, Bank& theBank) : Square(anID)
{
  taxAmount = amount;
  bank = theBank;
}
#ifndef BANK_H
#define BANK_H

class Bank
{
public:
  Bank(int, int, int);
  void getMoney(int);
  void giveMoney(int);
  void grantHouse();
  void grantHotel();

private:
  int sumMoney;
  int numOfHouses;
  int numOfHotels;

};

#endif

Upvotes: 26

Views: 37877

Answers (4)

Riz
Riz

Reputation: 31

bank = theBank; this statement means you are assigning obj1 to obj2 and it will call Assignment operator which is wrong as bank is of type reference it must be intialized as mentioned below

TaxSquare::TaxSquare(int anID, int amount, Bank& theBank) : Square(anID), bank(theBank) {}

Upvotes: 1

Karl Knechtel
Karl Knechtel

Reputation: 61478

“'TaxSquare::bank' must be initialized in constructor base/member initializer list”. What is wrong in the following code of the classes?

What is wrong is that TaxSquare::bank is not being initialized in the constructor base/member initialization list, exactly as it says.

"The constructor base/member initialization list" is the initialization list for the constructor in question, TaxSquare::TaxSquare(int, int, Bank&). You're already using it to initialize the base (Square). You must use it to initialize the bank member, because it is of a reference type. Things not specified in the initialization list get default-initialized, and there is no default-initialization for references, because they must always reference something, and there is no default something for them to reference.

Honestly, I find that using references for data members in C++ is more trouble than it's worth, 99% of the time. You're probably better off with a smart pointer, or even a raw one. But you should still initialize that with the initialization list, even if you could get away without. Same goes for the taxAmount, really.

// TaxSquare::TaxSquare(int anID, int amount, Bank& theBank) : Square(anID)
// That thing after the colon is the initialization list:      ^^^^^^^^^^^^
// So add the other members to it, and then notice that there is nothing left
// for the constructor body to do:
TaxSquare::TaxSquare(int anID, int amount, Bank& theBank) : 
Square(anID), taxAmount(amount), bank(theBank) {}

Upvotes: 7

vbar
vbar

Reputation: 61

The error is you're trying to assign through an uninitialized reference: a C++ reference cannot be assigned - the object it refers to is assigned instead - and so, if it's a member, it must be initialized in the initializer list (like the compiler says).

Upvotes: 5

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272467

You are attempting to assign to bank, not initialize it:

TaxSquare::TaxSquare(int anID, int amount, Bank& theBank) : Square(anID)
{
    // These are assignments
    taxAmount = amount;
    bank = theBank;
}

bank is a reference, and therefore it must be initialized. You do so by putting it in the initializer list:

TaxSquare::TaxSquare(int anID, int amount, Bank& theBank)
: Square(anID), taxAmount(amount), bank(theBank)
{}

Upvotes: 42

Related Questions