【发布时间】:2017-03-09 00:51:21
【问题描述】:
我想创建一个定义类的一些方法的抽象类。其中一些应该由基类(Base)实现,一些应该在 Base 中定义但被 Derived 覆盖,而另一些应该在 Base 中纯虚拟以强制在 Derived 中定义。
这当然是抽象类的用途。但是,我的应用程序只会直接使用 Derived 对象。因此,编译器应该在编译时确切地知道要使用哪些方法。
现在,因为此代码将在 RAM 非常有限的微控制器上运行,所以我很想避免实际使用虚拟类和这需要的 vtable。从我的测试来看,编译器似乎足够聪明,除非必须这样做,否则至少在某些情况下不会生成 vtable。但是我被告知永远不要相信编译器:是否可以将其作为编译的必要条件?
以下是一些代码示例:
类
class Base {
public:
Base() {}
virtual ~Base() {};
virtual int thisMustBeDefined() = 0;
virtual int thisCouldBeOverwritten() { return 10; }
int thisWillBeUsedAsIs() { return 999; }
};
class Derived : public Base {
public:
Derived() {}
~Derived() {}
int thisMustBeDefined() { return 11; }
};
没有 vtable
这没有 vtable,这是我想要的
int main() {
Derived d;
d.thisMustBeDefined();
}
是 vtable 1
由于我的编码草率,我错误地强制编译器使用多态性,因此需要一个 vtable。我怎样才能让这种情况引发错误?
int main() {
Base * d;
d = new Derived();
d->thisMustBeDefined();
}
是 vtable 2
这里我在任何时候都没有提到“Base”类,所以编译器应该知道所有方法都是在编译时预先确定的。但是它仍然会创建一个 vtable。这是我希望能够通过编译错误检测到这一点的另一个例子。
int main() {
Derived * d;
d = new Derived();
d->thisMustBeDefined();
}
换句话说,如果我编写的代码导致编译器为我的类生成一个 vtable,即使用多态性,我希望它是一个编译器错误。
【问题讨论】:
-
你错了——一旦你使用了 virtual 这个词,你就得到了该类的任何对象的 vtable;或任何由此而来的东西
-
恐怕我不是:我已经查看了所有三种情况的生成目标代码
-
如果您从不使用
Base,为什么它存在?确保没有生成支持多态的代码的方法是没有多态。 -
我会看看en.wikipedia.org/wiki/Curiously_recurring_template_pattern。这将能够实现“静态多态性”。
-
@MartinBonner “你可能不得不放弃强迫自己编写特定的方法。”不一定。您可以将静态检查添加到基类中以确保它们在派生类中的存在。
标签: c++ c++11 inheritance interface abstract-class