具有引用类成员的赋值运算符

时间:2011-12-26 12:38:04

标签: c++ vector reference operator-overloading

只要我的上一个问题Overloaded assignment operator causes warning about recursion中出现了新的问题,我就会被合理地要求将其作为新问题发布。我在类Player中有一个引用类成员,我想实现该类的复制构造函数和赋值运算符(=)。我必须提到的是,目的是函数vector.erase的精细工作,因为没有它,就我而言它无法正常工作。我使用vector:vector allPlayers; Player类的成员是:

class Player
{

  private:
  int ID;
  int pMoney;
  int doubleIndicator;
  int squarePosition;
  Bank& bank;
  string pName;
  Square* capturedSquare;
  multimap<string, PropertySquare*> squaresColBought;
  multimap<string, House*> housesColBuilt;

}

如果我想实现赋值运算符,是否必须避免使用引用作为类成员?地图成员怎么样?我该如何最终实现赋值运算符?

我不知道的另一个最重要的问题是当我擦除持有播放器的向量的迭代器时,指针类成员指向的对象会发生什么。有什么帮助吗?

3 个答案:

答案 0 :(得分:14)

C ++'reference'只能初始化,不能分配:

int value1(1), value2(2);
int& ref1 = value1; // OK
int& ref2; // compile error: reference not initialized
int& ref3=ref1; // OK: ref3 refers to the same variable as ref1
ref1=value2; // equivalent to 'value1=value2'.

因此,只能初始化包含引用的对象

确实如此:如果您需要在类上进行赋值,那么该类不能具有引用成员变量。 (事实上​​,它可以,但任务不能使这些成员引用另一个位置)

当你想到这一点时,它是有道理的:

参考概念为另一个变量定义“别名”。别名意味着您对引用执行的任何操作,实际上您对引用的位置执行了操作。将赋值应用于此别名时,实际上您将分配给引用的位置。如果您能够使用赋值将其指向其他位置,则引用的目的将会丢失。

如果后者是你需要的,你应该使用指针。

答案 1 :(得分:8)

当你想要一个赋值运算符时,我会避免使用引用成员。如果您使用(智能)指针,则可以执行

Player &operator=(Player const &other)
{
    bankPtr = other.bankPtr;
    // copy other members
}

在目前的情况下,bank = other.bank会复制other.bank的内容,而不是将this->bank指向other.bank引用的内容。

对于multimap类型的成员,可以毫无问题地复制它们,但请记住,您将获得密钥的“深层”副本(因为它们的类型为{{1} }}但是值的“浅”指针副本,所以你最终得到共享状态。您可能希望使用string作为值。

答案 2 :(得分:-2)

这确实是对c ++设计的破解,但是您可以在'this'上使用new放置。即

MyClass::MyClass(ReferenceType& referenceTarget):
    myReference(referenceTarget)
{}

MyClass& MyClass::operator=(const MyClass& other)
{
    new (this) MyClass(other.myReference);
    return *this;
}