Vin*_*ert 13
这被称为使课程"最终"或"一片叶子".有三种方法可以实现:简单的技术方法,更简单的非技术方法,以及稍微复杂的技术方法.
(简单)技术方法是使类的构造函数为私有,并使用Named Constructor Idiom 来创建对象.没有人可以创建派生类的对象,因为基类的构造函数将无法访问.如果您希望对象分配,则
new"命名构造函数"本身可以通过指针返回,或者如果您希望在堆栈上创建对象,则它们可以按值返回.(更简单的)非技术方法是在类定义旁边添加一个很大的丑陋评论.评论可以说,例如,
// We'll fire you if you inherit from this class甚至只是/*final*/ class Whatever {...};.一些程序员对此不以为然,因为它是由人而不是技术强制实施的,但不要贬低它的面值:它在实践中非常有效.一种稍微棘手的技术方法 是利用虚拟继承.由于大多数派生类的ctor需要直接调用虚基类的ctor,因此以下保证没有具体类可以从类继承
Fred:
class Fred;
class FredBase {
private:
friend class Fred;
FredBase() { }
};
class Fred : private virtual FredBase {
public:
...
};
Run Code Online (Sandbox Code Playgroud)
类
Fred可以访问FredBase的ctor,因为Fred它是朋友FredBase,但是没有派生自Fred的类可以访问FredBase的ctor,因此没有人可以创建派生自的具体类Fred.如果您处于极其空间受限的环境中(例如嵌入式系统或内存有限的手持设备等),您应该知道上述技术可能会添加一个内存字
sizeof(Fred).这是因为大多数编译器通过在派生类的对象中添加指针来实现虚拟继承.这是编译器特定的; 你的旅费可能会改变.
不,没有必要.如果你的类没有虚拟析构函数,那么从它派生它是不安全的.所以不要给它一个.
您可以使用这个技巧,从Stroustrup的FAQ中复制:
class Usable;
class Usable_lock {
friend class Usable;
private:
Usable_lock() {}
Usable_lock(const Usable_lock&) {}
};
class Usable : public virtual Usable_lock {
// ...
public:
Usable();
Usable(char*);
// ...
};
Usable a;
class DD : public Usable { };
DD dd; // error: DD::DD() cannot access
// Usable_lock::Usable_lock(): private member
Run Code Online (Sandbox Code Playgroud)
在C++ 0x(以及作为扩展,在MSVC中),您实际上可以使它非常干净:
template <typename T>
class final
{
private:
friend T; // C++0x, MSVC extension
final() {}
final(const final&) {}
};
class no_derived :
public virtual final<no_derived> // ah, reusable
{};
Run Code Online (Sandbox Code Playgroud)