【问题标题】:Condition in operator=运算符中的条件=
【发布时间】:2020-01-27 20:57:51
【问题描述】:

假设我有一个B 类型的对象,其中包含A 类型的对象。而A 包含一个无法更改的整数。来自B A 由非常量引用返回(因为它包含一些有用的方法):

class A {
private:
    int i;
public:
    A(int i) : i(i) {};

    void doSomethingNonConst() {}

    int getInt() {
        return i;
    }
}

class B {
public:
    A& getA();
}

但是有一个问题:我可以执行以下操作:getA() = A(5); 这当然会更改无法更改的整数。 我的解决方案是使用operator=,即仅在目标和源的整数相等时复制,否则抛出异常:

A& operator=(const A& a) {
    if (a.i == i) {
        //do copy
    } else
        //throw an exception
} 

这是好的设计解决方案吗?如果不是,那我怎样才能做得更好?也许,最好复制所有内容,但在外部代码中添加一些整数相等检查?

【问题讨论】:

  • @Yksisarvinen 你是个天才。谢谢
  • 这是一个糟糕的设计,因为错误只在运行时出现。使用 const 类型会在编译时出现,并且更可取。为什么不将int i 设为常量?

标签: c++ architecture


【解决方案1】:

而 A 包含一个无法更改的整数。

然后要么让intconst

class A {
private:
    const int i;
...

和/或在B const 中创建A 并返回const 参考::

class B {
private:
    const A a;
public:
    const A& getA();
}

【讨论】:

  • 第二种解决方案是不可接受的,因为正如我所说,A 包含一些有用且需要的非常量方法。但我会接受答案。
  • 你可以让一些需要的成员可变,可变成员可以通过const方法和const对象修改。
  • @wcobalt 听起来你应该有两个(或更多)类。
  • @PaulEvans 为什么以及我需要哪些课程?
  • @PaulEvans 以及如果我需要那个整数非常量该怎么办(因为 IRL 它不是一个整数,而是一个还包含一些需要的非常量方法的对象)?
【解决方案2】:

虽然您可以这样做,但它可能会使人们感到困惑,并且您必须在运行时处理它。通常更希望在编译时出现错误并完全防止“复制”。

在这种情况下,您可以制作整数 const,这将阻止隐式默认复制运算符。

class A {
private:
    const int i;
public:
    A(int i) : i(i) {};

    void doSomethingNonConst() {}

    int getInt() {
        return i;
    }
};
class B {
public:
    B() : a(5) {}
    A &getA() { return a; } // still non-const here
private:
    A a;
};
int main()
{
    B b;
    A otherA(60);
    // Compile error. GCC: use of deleted function 'A& A::operator=(const A&)'
    // 'A& A::operator=(const A&)' is implicitly deleted because the default definition would be ill-formed
    b.getA() = otherA;
}

否则,您可以明确摆脱运算符,例如如果由于其他原因您不能将变量设为 const 。在某些情况下,可能还需要通过 复制构造函数 阻止复制,其工作方式相同。

您可以通过删除默认运算符 A &operator = (const A &) = delete; 来做到这一点。

class A {
private:
    int i;
public:
    A(int i) : i(i) {};

    A (const A &) = delete;
    A &operator = (const A &) = delete;

    void doSomethingNonConst() {}

    int getInt() {
        return i;
    }
};
int main()
{
    B b;
    A otherA(60);
    b.getA() = otherA; // Compile error. GCC: use of deleted function 'A& A::operator=(const A&)'
}

【讨论】:

猜你喜欢
  • 2020-08-22
  • 2023-04-11
  • 2017-12-03
  • 2013-03-22
  • 1970-01-01
  • 2010-10-26
  • 2011-12-31
  • 2015-07-12
相关资源
最近更新 更多