9

我想知道你们是否可以帮助我。

这是我的.h:

Class Doctor {
   const string name;
   public:
       Doctor();
       Doctor(string name);
       Doctor & Doctor::operator=(const Doctor &doc);
}

和我的主要:

int main(){
    Doctor d1 = Doctor("peter");
    Doctor d2 = Doctor();
    d2 = d1;
}

我想做 operator= 功能。谁能帮我?注意 Doctor 上的 const 成员。

************编辑:********* 我的主要问题是我希望另一个类有一个属性,它是一个医生,就像一个病人有一个医生。但我希望能够改变我的医生。就像我正在看医生 A 但我想看医生 B。这将在我的其他班级 (Pacient) 中使用 setDoctor 函数来完成。如果是我编写代码,我会这样说:

class Patient{
    Doctor &d;
};

然后更改指针。但是,我使用的是一位老师制作的基本代码,它的类定义如下:

class Patient{
     Doctor d;
}

但我认为这是不可能的,因为在 Patient 类中使用 setDoctor() 时,我要么制作副本,要么更改变量本身。第一个没有任何区别,第二个由于 const 是不可能的。我对吗?

4

6 回答 6

10

你快到了。几个值得注意的点:

  • 名称不应被const限定。Aconst不能被修改,这正是我们在赋值运算符中想要的。

  • C++ 关键字是class而不是Class你的代码有它(它会给你编译错误)

  • 正如 Michael Burr 所说:“应该注意的是,如果该类仅包含已经正确支持赋值的其他类(如在本例中使用简单的字符串成员),则编译器生成的隐式 operator=() 将正常工作。” 在这里,就您而言,唯一的成员string具有适当的op=. 所以明确定义是多余的。

  • Meeh 的解决方案几乎就在那里。它唯一没有谈论的是自我分配。阅读常见问题 12

  • 赋值是三大成员函数FAQ 27.10之一。查一下。它说,实现 copy ctor、op= 或 dtor 之一的要求通常意味着您还需要实现另外两个。

更正后的代码示例应该是这样的:

class Doctor {
  string name;
  public:
    Doctor& operator=(Doctor const& o) { 
         if (&o != this) name = o.name;
         return *this;
    }
  // ...
};
于 2009-04-12T22:53:42.310 回答
5

正确定义赋值构造函数以使其异常安全的标准方法是根据复制构造函数来定义它。

class Doctor
{
    public:
        Doctor& operator=(Doctor const& rhs)
        {
            if (this != &rhs)
            {
                Doctor  tmp(rhs);  // Use copy constructor here
                this->swap(tmp);   // Now Swap
            }
            return *this;
        }
        void swap(Doctor& rhs) throws()
        {
            std::swap(.....); // swap each member variable.
        }
};

通过这样做可以使它异常安全。
请注意,您只需要将交换设置为无抛出方法,如果您使用 STL 对象,这相对简单,因为它们都为这种情况定义了无抛出交换,boost 和所有好的库也是如此(因此您应该遵循套件)。

如果这出错了,他们在使用复制构造函数时会出错。此时,您尚未修改自己的对象,因为您正在将构造复制到临时对象中。因此,您提供了良好的异常安全性,因为您的对象仍未更改。

于 2009-04-13T06:08:31.657 回答
2

声明是Doctor &operator=(const Doctor &other); (即删除医生::)

从那里你需要使用 const_cast<> 来删除成员变量的 const-ness 以使其工作。请注意,只有心碎在于您选择的道路。

我建议从成员声明中删除 const ,而是根据需要使成员函数 const 以表明它们不会影响对象。(例如,如果您有一个访问器成员函数,您可以声明 const: string getName() const { return m_name; }

于 2009-04-12T22:48:32.557 回答
1

正如许多人之前所说,成员是“const”表示它必须在创建期间进行初始化,并且不应更改。如果您必须为这种情况编写一个赋值运算符并且您不能跳过该成员变量的赋值,那么将其设为“可变”。

记住; 从 C++ 标准来看,“抛弃最初声明的 const 变量的 const 是未定义的行为。”

HTH,阿拜

于 2009-04-13T04:34:28.807 回答
0

由于您的名字是 const,因此“更改”它的唯一方法是通过构造函数。如果你想使用 = 操作符,你需要“unconst”这个字符串。

..如果你不想“unconst”字符串,你可以通过创建一个复制构造函数来获得一些相同的行为:

Doctor(const &Doctor d);

..并实施它:

Doctor::Doctor(const &Doctor d)
   : name(d.name)
{
//Im pretty sure you have access to private attributes here
// My C+ is a bit rusty :) If not, make a const string getName() method
}
于 2009-04-12T22:44:28.353 回答
0

您还想将返回类型更改为 const&:

const Doctor& operator=(const Doctor &doc);

省略 const 将使以下代码可编译,而实际上它们是无效的:

(A = B) = C;

等于以下内容:(这可能是预期的)

A = B = C;
于 2009-04-13T14:07:46.107 回答