我在嵌入式环境中使用 C,其中虚拟函数的运行时确实很重要。我读过关于可以内联虚拟函数的罕见情况,例如:内联虚函数真的是无意义的吗?接受的答案指出,只有在运行时已知确切的类时,例如在处理本地、全局或静态对象(不是指针或对基类型的引用)时,才有可能进行内联。我理解这背后的逻辑,但我想知道在以下情况下是否也可以内联:
class Base {
public:
inline virtual void x() = 0;
}
class Derived final : Base {
public:
inline virtual void x(){
cout << "inlined?";
}
}
int main(){
Base* a;
Derived* b;
b = new Derived();
a = b;
a->x(); //This can definitely not be inlined.
b->x(); //Can this be inlined?
}
从我的观点来看,编译器应该在编译时知道的最终类型,因为它是一个最终类。在这种情况下,是否可以内联虚拟函数?如果不是,那么为什么?如果是,那么gcc编译器(分别是avr-gcc)会这样做吗?
谢谢
第一步称为去中心化;其中函数调用不经过虚拟调度。
编译器可以并且确实将final方法和final类的方法去虚化。这几乎是final的全部内容。
一旦去货币化,方法就可以内联。
有些编译器有时可以证明*
的静态类型,甚至可以将其反序列化。这不太可靠。Godbolt的编译器资源管理器有助于了解哪些特定的优化可能发生,以及如何失败。
其实,类似的问题这里问过,那里问过,但回答都不满意。代码示例是 输出为 关于 由于是虚函数,派生类不实现它,因此程序将调用; 则程序将调用; 是一个常规函数,程序将调用; 也是一个常规函数,程序将调用; 我不明白的部分来了,不是虚函数,是属于的指针,基本上只能访问中的函数!但输出是 相比之下,会像我想的那样调用。 在基类指针只能访问基类和虚函数中定义的函数的原则与实际输出之间似乎存在矛盾。原因也无
为什么一个虚函数在派生类中默认是虚的,甚至不可能在派生类中完全移除虚性,这有什么好的理由吗? 我希望这种行为的原因与我不希望默认情况下每个函数都是的原因相同。编译器可能会生成牺牲性能的vtables。 基类应该有一个vtable(我想要多态性在那里),但派生类没有vtable(我不希望多态性在那里,为什么我要那样,只是因为它派生了一个具有多态性的类?)。 我想解决的问题是更好地理解虚函数。我只是没
我正在学习面向对象的C,并有一个关于虚拟/纯虚拟和多级继承的问题。 假设我有这样的简单代码: 我的理解是,除非getWidth被指定为虚拟,否则多态将使用“Base”类的函数。我的意思是r-的最终调用 在这种情况下,我注意到如果我删除Shape中的纯虚拟声明,我们会得到我刚才描述的行为。在基类中有一个纯虚函数会自动使该函数的所有定义都是虚的吗?
从已有的对象类型出发建立一种新的对象类型,使它部分或全部继承原对象的特点和功能,这是面向对象设计方法中的基本特性之一。继承不仅简化了程序设计方法,显著提高了软件的重用性,而且还使得软件更加容易维护。派生则是继承的直接产物,它通过继承已有的一个或多个类来产生一个新的类,通过派生可以创建一种类族。 继承 基本概念 在定义一个类A时,若它使用了一个已定义类B的部分或全部成员,则称类A继承了类B,并称
和构造函数类似,析构函数也不能被继承。与构造函数不同的是,在派生类的析构函数中不用显式地调用基类的析构函数,因为每个类只有一个析构函数,编译器知道如何选择,无需程序员干涉。 另外析构函数的执行顺序和构造函数的执行顺序也刚好相反: 创建派生类对象时,构造函数的执行顺序和继承顺序相同,即先执行基类构造函数,再执行派生类构造函数。 而销毁派生类对象时,析构函数的执行顺序和继承顺序相反,即先执行派生类析构
主要内容:构造函数的调用顺序,基类构造函数调用规则前面我们说基类的成员函数可以被继承,可以通过派生类的对象访问,但这仅仅指的是普通的成员函数, 类的构造函数不能被继承。构造函数不能被继承是有道理的,因为即使继承了,它的名字和派生类的名字也不一样,不能成为派生类的构造函数,当然更不能成为普通的成员函数。 在设计派生类时,对继承过来的成员变量的初始化工作也要由派生类的构造函数完成,但是大部分基类都有 private 属性的成员变量,它们在派生类中无法