【发布时间】:2012-09-15 19:16:46
【问题描述】:
我编写了一个宏,可以在类定义周围添加它,从而有效地完成它(防止子类化)。这种最终确定方法是一种相当常见的技术,在C++ FAQ 中有说明:
#define FINALIZE(NAME,...) \
NAME##Finalizer {\
private:\
friend class NAME;\
inline NAME##Finalizer(void) {}\
};\
class NAME : public virtual NAME##Finalizer, __VA_ARGS__
例如:
class FINALIZE(Fred) {};
//The above line evaluates to:
// class FredFinalizer {
// private:
// friend class Fred;
// inline FredFinalizer(void) {}
// };
// class Fred : public virtual FredFinalizer, {};
class George {};
class FINALIZE(Fred2, public George) {};
//The above line evaluates to:
// class Fred2Finalizer {
// private:
// friend class Fred2;
// inline Fred2Finalizer(void) {}
// };
// class Fred2 : public virtual Fred2Finalizer, public George {};
class Velma : public Fred { Velma(void) {} /*Note compile error*/ };
class Velma2 : public Fred2 { Velma2(void) {} /*Note compile error*/ };
这很好用。问题是我现在想要一种“禁用”宏的方法。那就是:
class FINALIZE(Fred) {};
//The above line evaluates to:
// class Fred {};
class George {};
class FINALIZE(Fred2, public George) {};
//The above line evaluates to:
// class Fred2 : public George {};
问题在于class Fred2 : public George {}; 与没有继承的情况(class Fred {};)冲突:在第一种情况下,必须始终有一个冒号,在第二种情况下,必须没有。请注意,启用宏时这不是问题,因为类always 继承自至少 NAME##Finalizer 类。
我怎样才能写一个宏来做到这一点?
【问题讨论】:
-
是否有理由让解决方案成为宏?
-
你会接受一个虚拟基类吗?
-
这个问题并不重要,但如果这是您的最终目标(防止继承),您可能希望私有化虚拟基类。看来这将是您链接的描述中非常关键的部分。
-
@DeadMG 他这样做是为了防止一个类成为派生的基础,这是 Java 狂热者非常熟悉的东西。
-
CraigNelson,正确,尽管我反对隐含的想法,即我喜欢 Java。相反,除了 C#,我最讨厌现代语言了。 DeadMG,我一直在抱怨,因为用户愚蠢地继承了明确标记为“不继承自”的类。编译时解决方案是有序的。
标签: c++ inheritance macros