防止在 C++ 中调用基赋值运算符
Posted
技术标签:
【中文标题】防止在 C++ 中调用基赋值运算符【英文标题】:Prevent call to base assignment operator in 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
(和Derived
friend
)方法...
【参考方案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 关键字。 :)以上是关于防止在 C++ 中调用基赋值运算符的主要内容,如果未能解决你的问题,请参考以下文章
C++的探索路12继承与派生之高级篇--派生类与赋值运算符及多重继承