我想创建一个定义类的一些方法的抽象类.其中一些应该由基类(Base)实现,一些应该在Base中定义但是由Derived覆盖,而其他应该在Base中是纯虚拟的,以强制Derived中的定义.
这当然是抽象类的用途.但是,我的应用程序只会直接使用Derived对象.因此,编译器应该在编译时确切地知道要使用哪些方法.
现在,因为这段代码将在内存非常有限的微控制器上运行,所以我很想避免实际使用带有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; }
};
Run Code Online (Sandbox Code Playgroud)
这没有vtable,是我想要的
int main() {
Derived d;
d.thisMustBeDefined();
}
Run Code Online (Sandbox Code Playgroud)
由于我的草率编码,我错误地强迫编译器使用多态,因此需要一个vtable.如何让这个案例抛出错误?
int main() {
Base * d;
d = new Derived();
d->thisMustBeDefined();
}
Run Code Online (Sandbox Code Playgroud)
在这里,我没有在任何时候提到类"Base",因此编译器应该知道所有方法都是在编译时预先确定的.然而,它仍然创造了一个vtable.这是我希望能够通过编译错误检测到这一点的另一个例子.
int main() …Run Code Online (Sandbox Code Playgroud) 很抱歉这个问题的标题含糊不清,但我不确定如何确切地问这个问题.
以下代码在Arduino微处理器上执行时(为ATMega328微处理器编译的c ++)工作正常.返回值显示在代码中的注释中:
// Return the index of the first semicolon in a string
int detectSemicolon(const char* str) {
int i = 0;
Serial.print("i = ");
Serial.println(i); // prints "i = 0"
while (i <= strlen(str)) {
if (str[i] == ';') {
Serial.print("Found at i = ");
Serial.println(i); // prints "Found at i = 2"
return i;
}
i++;
}
Serial.println("Error"); // Does not execute
return -999;
}
void main() {
Serial.begin(250000);
Serial.println(detectSemicolon("TE;ST")); // Prints "2"
}
Run Code Online (Sandbox Code Playgroud)
如预期的那样,它输出"2"作为第一个分号的位置.
但是,如果我将detectSemicolon …