Operator =在C ++中使用Const变量进行过载

时间:2009-04-12 22:34:23

标签: c++ operators operator-overloading const conversion-operator

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

这是我的.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()我会复制或改变varable本身。第一个没有任何区别,第二个是不可能的,因为const。我是对的吗?

6 个答案:

答案 0 :(得分:7)

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

  • 该名称不应为const限定。无法修改const,这正是我们在赋值运算符中所需要的。

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

  • 正如迈克尔·伯尔所说:“应该注意的是,如果类只包含已经正确支持赋值的其他类(在本例中使用简单的字符串成员),则隐式的,编译器生成的运算符= ()会工作得很好。“在您的情况下,唯一的成员string具有适当的op=。所以明确定义是多余的。

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

  • 作业是三大成员函数之一FAQ 27.10。仔细看看。它说,要求实现复制ctor,op =或dtor中的任何一个通常意味着你还需要实现其他两个。

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

class Doctor {
  string name;
  public:
    Doctor& operator=(Doctor const& o) { 
         if (&o != this) name = o.name;
         return *this;
    }
  // ...
};

答案 1 :(得分:3)

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

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和所有好的库一样(所以你应该按照套件)。

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

答案 2 :(得分:2)

声明为Doctor &operator=(const Doctor &other);(即删除Doctor ::)

从那里你需要使用const_cast<>删除成员变量的常量以使其工作。请注意,只有心碎位于您选择的路径中。

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

答案 3 :(得分:1)

正如之前许多人所说,成员'const'表示它必须在创建过程中初始化,并且不应该改变。 如果你必须为这种情况编写一个赋值运算符,你就不能跳过该成员变量的赋值,那么就把它变成'可变'。

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

HTH, 阿沛

答案 4 :(得分:0)

因为你的名字是const,所以“改变”它的唯一方法是通过构造函数。如果要使用=运算符,则需要“取消”字符串。

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

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
}

答案 5 :(得分:0)

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

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

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

(A = B) = C;

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

A = B = C;