提问人:rodrigocfd 提问时间:4/14/2017 更新时间:4/14/2017 访问量:270
阻止在 C++ 中调用基本分配运算符
Prevent call to base assignment operator in C++
问:
我的库里有这两个类:
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
答:
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_Class
void 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的重新设计。我们甚至可能不得不使用虚拟关键字。:)
评论
this->
Derived
Base
private
Derived
friend