在Java中,您可以将方法标记为final,以使其无法覆盖.
在C#中,您必须将方法标记为虚拟,以便可以覆盖.
这是否意味着在C#中你应该将所有方法标记为虚拟(除了一些你不想被覆盖的方法),因为很可能你不知道你的类可以以什么方式被继承?
我知道PHP或Java的虚拟方法.
它们如何在Python中实现?
或者我要在抽象类中定义一个空方法并覆盖它?
C++中的赋值运算符可以是虚拟的.为什么需要它?我们可以让其他运营商也虚拟化吗?
可能重复:
C++静态虚拟成员?
我们可以拥有静态虚函数吗?如果没有,那么为什么?
class X
{
public:
virtual static void fun(){} // Why we cant have static virtual function in C++?
};
Run Code Online (Sandbox Code Playgroud) 我知道虚函数有一个解除引用调用方法的开销.但我想现代建筑速度几乎可以忽略不计.
更新:
总结来自Jon Skeet的答案如下:
明确地让某人意识到他们正在继承功能[这本身就有潜在的风险[(检查Jon的回应)] [和潜在的小的性能提升]之间需要权衡,需要通过权衡来减少灵活性,增加代码更多,以及更陡峭的学习曲线.
不同答案的其他原因:
虚函数不能内联,因为内联必须在运行时发生.当您希望通过内联功能获益时,这会对性能产生影响.
可能还有其他原因,我很想知道并总结它们.
维基百科在C++ 11 final修饰符上有以下示例:
struct Base2 {
virtual void f() final;
};
struct Derived2 : Base2 {
void f(); // ill-formed because the virtual function Base2::f has been marked final
};
Run Code Online (Sandbox Code Playgroud)
我不明白引入虚拟功能并立即将其标记为最终功能.这只是一个不好的例子,还是有更多的东西?
对于此代码:
class B1{
public:
virtual void f1() {}
};
class D : public B1 {
public:
void f1() {}
};
int main () {
B1 *b1 = new B1();
D *d = new D();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译后,我得到的vtable g++ -fdump-class-hierarchy是:
Vtable for B1
B1::_ZTV2B1: 3u entries
0 (int (*)(...))0
8 (int (*)(...))(& _ZTI2B1)
16 B1::f1
Vtable for D
D::_ZTV1D: 3u entries
0 (int (*)(...))0
8 (int (*)(...))(& _ZTI1D)
16 D::f1
Run Code Online (Sandbox Code Playgroud)
我无法理解像(int()(...))0*这样的条目对应的内容.当然它意味着类似,它是一个函数,它返回一个int并获取无限数量的参数,我不明白任何事情.这个函数指针对应哪个函数?你怎么知道的?我是64位机器.
第二个函数指针的末尾有一个地址?对应的对象是谁?
编辑
我使用的编译器是g ++:
g++ -v …Run Code Online (Sandbox Code Playgroud) 在Stack Overflow post中检查C++ 11中的对象类型,我有以下注释:
在C++ 11中你实际上想要做
virtual ~A() = default;其他事情,你将失去隐含的移动构造函数.
什么是virtual ~A() = default;?为什么隐式移动构造函数会丢失virtual ~A() {}?
据我所知,override关键字声明给定的声明实现了一个基本virtual方法,如果找不到匹配的基本方法,编译应该失败.
我对该final关键字的理解是它告诉编译器没有类会覆盖这个virtual函数.
那是override final多余的吗?好像编译好了.哪些信息override final传达的final不是?这种组合的用例是什么?
c++ ×7
c# ×2
c++11 ×2
final ×2
java ×2
destructor ×1
gcc ×1
inheritance ×1
methods ×1
overriding ×1
python ×1
virtual ×1
vtable ×1