重载all-const类型的复制赋值运算符的正确方法是什么?

时间:2012-09-11 13:12:10

标签: c++ overloading operator-keyword

假设我有这样的结构:

struct Foo
{
  const int bar;
  const char baz;

  Foo& operator=(const Foo& other)
  {
    memcpy(this,&other,sizeof(Foo)); //How am I supposed to write this decently?
    return *this;
  }
}

我希望Foo的所有字段都是final,我希望Foo类型的变量与其他原始值类型一样。说,int,我们当然可以写这样的东西:

 int i = 0;
 i = 42;

 Foo foo = {007,'B'}
 foo = {42,'X'}

然而,对于我可怜的Foo类型,我是否必须使用memcpy这样的方法来解决类型安全检查?我知道我可以删除const修饰符,将字段标记为私有并添加一些getter,但这不是重点。我只想知道是否有一种不错的方式来编写=运算符的内容。

提前致谢!

~~~~~

查看以下示例:

//If the = op is not implemented, this won't compile
Foo stat;
for(int i=0;i!=100;++i)
{
  stat = func(i);
  if(stat.bar == 0)...
}

//But weird thing is, if I declare the 'stat' inside the for block, it works just fine with gcc
for(int i=0;i!=100;++i)
{
  Foo stat = func(i); 
  //printf("%p\n",&stat); => same variable same address!!
  if(stat.bar == 0)...
}

这对你有意义吗?

3 个答案:

答案 0 :(得分:6)

在C ++中,复制赋值对于全部const类型毫无意义。不要实现它。

使用所有有意义的const类型,但要注意此类型的行为与int相似,因为{{1}在C ++中根本不是int,除非你声明它。

答案 1 :(得分:3)

体面在这种情况下编写它的方法是:

Chunk& operator=(const Foo& other) = delete;

(或private pre-C ++ 11)

如果您的所有成员都是const,那么您为什么要更改它们呢?

答案 2 :(得分:0)

没有好办法,我同意其他答案,你应该重新考虑设计。

但如果你仍然认为这对你的问题来说是最不邪恶的,还有更多选择:

Foo& operator=(const Foo& other)
{
    const_cast<int&>(bar) = other.bar;
    const_cast<char&>(baz) = other.baz;
    return *this;
}

或者

#include <memory>

// Foo must never be used as a base class!
// If your compiler supports the c++11 final feature:
struct Foo final
{ /*...*/ };

Foo& operator=(const Foo& other)
{
    if (this != &other) {
        this->~Foo();
        new(this) Foo(other);
    }
    return *this;
}