我正在阅读《Effective C++ 第三版》(作者为Scott Meyers)。
他说通常不建议继承一个不包含虚函数的类,因为如果你以某种方式将派生类的指针转换为基类的指针,然后使用 delete
删除它可能会导致未定义的行为。
这是他提供的(人工制造的)例子:
class SpecialString: public std::string{
// ...
}
SpecialString *pss = new SpecialString("Impending Doom");
std::string *ps;
ps = pss;
delete ps; // undefined! SpecialString destructor won't be called
我理解为什么会出现错误,但是在 SpecialString
类中是否有任何方法可以防止像 ps = pss
这样的情况发生?
Meyers 指出(在书的不同部分)一种常见的技术是,声明一个特定的函数但故意不定义它来明确禁止某些行为在类中被允许。他给出了一个例子:复制构造。例如,对于不想允许复制构造的类,声明一个私有复制构造函数但不定义它,这样任何尝试使用它的操作都会导致编译时错误。
我知道这个例子中的 ps = pss
不是复制构造,只是想知道是否有其他方法可以明确地防止这种情况发生(除了 "不要那样做" 的答案)。
SpecialString
禁止公共访问其new
运算符,并要求使用工厂函数来返回一个自定义的智能指针类型,该类型不会暴露原始指针值。 - Dai=
来进行指针赋值,因为指针是标量。 - Daistd::string
时,您实际上签署的合同的一部分是SpecialString
[isa](https://en.wikipedia.org/wiki/Is-a)字符串,并且`ps = pss;`是完全合法的。有人可能会使用一些巫术或模板魔法来限制此操作,但结果可能会比“不要这样做”更加混乱。 - user4581301unique_ptr<T, default_deleter<T>>
应该禁用那种转换... - aschepler