阻止在 C++ 中调用基本分配运算符

Prevent call to base assignment operator in C++

提问人:rodrigocfd 提问时间:4/14/2017 更新时间:4/14/2017 访问量:270

问:

我的库里有这两个类:

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

C++ 继承 赋值运算符

评论

0赞 Pete Becker 4/14/2017
顺便说一句,这四种用途都不需要。this->
0赞 rodrigocfd 4/14/2017
我知道这一点,这只是为了清楚起见(即使它足够明显)。谢谢。
0赞 cdhowie 4/14/2017
您可以将赋值运算符设为私有,然后结交 ?DerivedBase
0赞 Jarod42 4/14/2017
您可以使方法(和)...privateDerivedfriend

答:

2赞 Kenny Ostrom 4/14/2017 #1

当我将标题更改为此时

class Derived : private Base

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

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

评论

0赞 Oliver Charlesworth 4/14/2017
特别是最后一句话+1。不要依赖您的客户知道以正确的顺序调用事物。
0赞 Kenny Ostrom 4/14/2017
另外,如果 Derived 中的函数不够用,那么考虑一个接口类,这样它们就知道它们能做什么和不能做什么(编译器也知道)。
0赞 rodrigocfd 4/15/2017
@kenny但是这样我就不能将对象传递给像这样的函数了,对吧?VC++ 给我错误 C2243:“从'User_Class *'到'Base &'的转换存在,但无法访问”。User_Classvoid abc(Base& b)
0赞 Kenny Ostrom 4/15/2017
如果你想限制客户端对类内部的访问,那很好,但当然,你还需要做一些工作来让客户端访问他们确实需要的东西。例如,为什么客户端使用采用 Base 的函数?那不应该是无效 abc(Derived &d) 吗?
1赞 Kenny Ostrom 4/16/2017
如果他们需要一部分 Base private,一部分 Base public,那么将 Base 分成两个类?我们已经超出了我回答的原始问题的范围。你想要的是完全可以实现的,但可能需要一些OO的重新设计。我们甚至可能不得不使用虚拟关键字。:)