【问题标题】:Prevent call to base assignment operator in C++防止在 C++ 中调用基赋值运算符
【发布时间】:2017-09-10 19:48:51
【问题描述】:

我的库中有这两个类:

class Base {
    int _handler;
protected:
    Base() = default;

    Base& operator=(int h) {
        this->_handler = h;
        return *this;
    }
};

class Derived : public Base {
protected:
    Derived() = default;

    void initialize() {
        this->Base::operator=(12345); // internal stuff
    }
};

Derived 类可供用户继承。他应该这样做:

class User_Class : public Derived {
    void foo() {
        this->initialize();
    }
};

但相反,他这样做:

class User_Class : public Derived {
    void foo() {
        this->Base::operator=(999); // no, you broke it!
    }
};

如何防止调用Base 赋值运算符?

【问题讨论】:

  • 顺便说一句,this-> 的四种用法都不需要。
  • 我知道,这只是为了清楚起见(即使它足够明显)。谢谢。
  • 您可以将赋值运算符设为私有,然后将Derived 设为Base 的朋友?
  • 你可以使用private(和Derivedfriend)方法...

标签: c++ inheritance assignment-operator


【解决方案1】:

当我将标题更改为此

class Derived : private Base

编译器立即阻止对 operator= 的调用,并使用“无法访问在类 'Base' 中声明的不可访问成员”,但是调用初始化的代码正常工作,因为它是可访问的。

但是,您还应该在 Derived 中覆盖 operator=,并让它检查它是否已被初始化。不要让客户端类处理内部簿记。

【讨论】:

  • +1 尤其是最后一句话。不要依赖您的客户知道以正确的顺序调用事物。
  • 补充说明,如果 Derived 中的函数不够用,那就考虑一个接口类,这样他们就知道自己能做什么,不能做什么(编译器也知道)。跨度>
  • @kenny 但是我不能将User_Class 对象传递给void abc(Base& b) 这样的函数,对吧? VC++ 给我错误 C2243:“从 'User_Class *' 到 'Base &' 的转换存在,但无法访问”。
  • 如果你想限制客户端对类内部的访问,那很好,但当然你需要做一些工作来让客户端访问他们真正需要的东西。例如,为什么客户端使用带 Base 的函数?那不应该是 void abc(Derived &d) 吗?
  • 如果他们需要Base私有的一部分和Base公共的一部分,那么将Base分成两个类?我们已经超出了我回答的原始问题的范围。您想要的绝对可以实现,但可能需要重新设计一些面向对象。我们甚至可能不得不使用 virtual 关键字。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-03
  • 1970-01-01
  • 1970-01-01
  • 2011-07-29
  • 1970-01-01
  • 2020-02-20
  • 2011-12-12
相关资源
最近更新 更多