Ссылка как инициализация члена класса - PullRequest
20 голосов
/ 27 ноября 2011

Я хочу инициализировать свойство класса, который содержит ссылку на другой класс, передавая такую ​​ссылку в качестве параметра конструктору. Однако я получаю сообщение об ошибке:

«TaxSquare :: bank должен быть инициализирован в базе конструктора / в списке инициализаторов элементов». Что не так в следующем коде классов?

#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

Ответы [ 4 ]

32 голосов
/ 27 ноября 2011

Вы пытаетесь присвоить bank, а не инициализировать его:

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

bank является ссылкой, и поэтому она должна быть инициализирована. Вы делаете это, помещая это в список инициализатора:

TaxSquare::TaxSquare(int anID, int amount, Bank& theBank)
: Square(anID), taxAmount(amount), bank(theBank)
{}
4 голосов
/ 27 ноября 2011

«TaxSquare :: bank должен быть инициализирован в базе конструкторов / в списке инициализаторов элементов». Что не так в следующем коде классов?

Что неправильно в том, что TaxSquare::bank не инициализируется в списке инициализации базы / члена конструктора, в точности так, как он говорит.

«Список инициализации базы / члена конструктора» - это список инициализации для рассматриваемого конструктора, TaxSquare::TaxSquare(int, int, Bank&). Вы уже используете его для инициализации базы (Square). Вы должны использовать его для инициализации члена bank, поскольку он имеет ссылочный тип. Вещи, не указанные в списке инициализации, инициализируются по умолчанию, и для ссылок нет инициализации по умолчанию, потому что они всегда должны ссылаться на что-то, и для них нет ссылок по умолчанию.

Честно говоря, я считаю, что использование ссылок для элементов данных в C ++ - это больше проблем, чем стоит, 99% времени. Вы, вероятно, лучше с умным указателем, или даже необработанным. Но вы должны по-прежнему инициализировать это с помощью списка инициализации, даже если вы можете обойтись без него. То же самое касается taxAmount, действительно.

// 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) {}
4 голосов
/ 27 ноября 2011

Ошибка в том, что вы пытаетесь назначить через неинициализированную ссылку: ссылка C ++ не может быть назначена - объект, на который она ссылается, назначается взамен - и поэтому, если это член, он должен быть инициализирован в списке инициализатора ( как говорит компилятор).

1 голос
/ 25 ноября 2014

банк = банк;этот оператор означает, что вы присваиваете obj1 для obj2, и он будет вызывать оператор присвоения, который является неправильным, поскольку банк относится к типу, его необходимо инициализировать, как указано ниже

TaxSquare :: TaxSquare (int anID, int amount, Bank & theBank): Square (anID), банк (theBank) {}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...