问题标签 [virtual-functions]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 覆盖虚函数时的异常说明
考虑以下代码:
编译时,它说派生类 B 与 A 相比具有更宽松的抛出说明符。这有什么重要性?如果我们尝试交换它们的异常规范,使得 A::f() 抛出 int 和 double 而 B::f() 只抛出 int,则不会出现错误。
c++ - 为什么我们需要 C++ 中的虚函数?
我正在学习 C++,我刚刚进入虚拟函数。
从我读到的(在书中和在线)中,虚函数是基类中的函数,您可以在派生类中覆盖它们。
但是在本书的前面,在学习基本继承时,我能够在派生类中重写基函数,而无需使用virtual
.
那么我在这里错过了什么?我知道虚函数还有更多,而且它似乎很重要,所以我想弄清楚它到底是什么。我只是无法在网上找到一个简单的答案。
c++ - 虚拟类分段错误
我正在开发一个图形应用程序。它大量使用了虚拟类。我遇到了一些无法调试的分段错误。
此应用程序中的主要类是:
- 形状(一个虚拟类)
- 长方形
- 多边形
- 圆圈
- 图片(本质上是形状的集合)
这是我的代码适用部分的简短副本:
这是一个显示一些信息的 gdb 会话:
我已经把头撞在墙上几个小时了,现在试图弄清楚这件事。它与 Picture 类的 Graphic 成员有关。但是,我看不到它是如何拼凑起来产生分段错误的。
编辑:
这是 testpicture.cpp 中创建 Graphics 对象的部分:
Graphic 也是一个虚拟类。在这种情况下,PSGraphic 继承自它。
.net - C++ 与 C++/CLI:虚函数参数的常量限定
[以下所有内容均使用 Visual Studio 2008 SP1 进行了测试]
在 C++ 中,参数类型的 const 限定不影响函数的类型(8.3.5/3:“删除任何修改参数类型的 cv-qualifier”)
因此,例如,在以下类层次结构中,Derived::Foo
覆盖Base::Foo
:
考虑 C++/CLI 中的类似层次结构:
如果我然后创建一个实例Derived
:
它编译时没有错误或警告。当我运行它时,它会引发以下异常,然后终止:
ClrVirtualTest.exe 中出现“System.TypeLoadException”类型的未处理异常
附加信息:“Derived”类型中的方法“Foo”...没有实现。
该异常似乎表明参数的 const 限定确实会影响 C++/CLI 中函数的类型(或者,至少它会以某种方式影响覆盖)。但是,如果我注释掉包含定义的行Derived::Foo
,编译器会报告以下错误(在main
实例化的行上Derived
):
错误 C2259:“派生”:无法实例化抽象类
如果我将 const 限定符添加到参数 ofDerived::Foo
或从参数中删除 const 限定符Base::Foo
,它将编译并运行而没有错误。
我认为如果参数的 const 限定影响函数的类型,如果派生类虚函数中参数的 const 限定与基类 virtual 中参数的 const 限定不匹配,我应该得到这个错误功能。
如果我将Derived::Foo
's 参数的类型从 anint
更改为 a double
,我会收到以下警告(除了上述错误,C2259):
警告 C4490:“覆盖”:错误使用覆盖说明符;'Derived::Foo' 与基 ref 类方法不匹配
所以,我的问题是,函数参数的 const 限定是否会影响 C++/CLI 中函数的类型?如果是这样,为什么会编译,为什么没有错误或警告?如果不是,为什么会抛出异常?
c++ - 虚函数问题
我在 VSTS 2008 中使用本机 C++。关于虚函数的快速问题。在下面的示例中,如果我在 Derived 类中将 Foo 声明为“virtual void Foo()”或“void Foo()”,有什么区别吗?对派生自 Derived 类的任何未来类有何影响?
c++ - 如何以良好的风格覆盖虚函数?[C++]
伙计们,我知道这个问题非常基本,但我在少数出版物(网站、书籍)中遇到过不同风格的覆盖虚拟功能。我的意思是:如果我有基类:
在一些出版物中,我看到一些作者会说:
有些人仍然会在 void 之前重复 virtual 关键字。哪种覆盖形式的风格很好?谢谢您的回答。
c++ - 以“= 0”结尾的 C++ 头文件和函数声明
我在 .h 文件中有以下代码,但我不确定赋值语句的作用以及如何正确调用它?
我认为该函数默认返回值 0 但由于该函数返回 void 我有点困惑。任何人都可以对此发表评论,也许会说我如何引用这个作业,我的意思是它在 C++ 行话中是如何调用的?
谢谢。
c++ - 从基类指针 C++ 访问子类成员
我有一组自定义类学生对象。CourseStudent 和 ResearchStudent 都继承自 Student,Student 的所有实例都是其中之一。
我有一个函数来遍历数组,确定每个学生的子类型,然后在它们上调用特定于子类型的成员函数。
问题是,因为这些函数没有重载,所以在Student中是找不到的,所以编译器就大惊小怪了。
如果我有一个指向 Student 的指针,有没有办法获得指向该 Student 子类型的指针?我需要在这里做一些假演员来解决编译时错误吗?
java - 为什么Java的invokevirtual需要解析被调用方法的编译时类?
考虑这个简单的 Java 类:
我想讨论一下 c.foo() 行发生了什么。
原始的,误导性的问题
注意:并非所有这些都发生在每个单独的调用虚拟操作码上。提示:如果你想了解 Java 方法调用,不要只阅读 invokevirtual 的文档!
在字节码级别,c.foo() 的核心将是 invokevirtual 操作码,并且根据 invokevirtual的文档,或多或少会发生以下情况:
- 查找在编译时类 MyClass 中定义的 foo 方法。(这涉及到首先解析 MyClass。)
- 做一些检查,包括: 验证 c 不是初始化方法,并验证调用 MyClass.foo 不会违反任何受保护的修饰符。
- 找出实际调用的方法。特别是查找 c 的运行时类型。如果该类型具有 foo(),则调用该方法并返回。如果不是,则查找 c 的运行时类型的超类;如果该类型有 foo,则调用该方法并返回。如果不是,查找c的运行时类型的超类的超类;如果该类型有 foo,则调用该方法并返回。等等。如果找不到合适的方法,则报错。
单独的步骤#3 似乎足以确定调用哪个方法并验证所述方法是否具有正确的参数/返回类型。所以我的问题是为什么首先要执行步骤#1。可能的答案似乎是:
- 在第 1 步完成之前,您没有足够的信息来执行第 3 步。(乍一看似乎不可信,所以请解释一下。)
- 在 #1 和 #2 中完成的链接或访问修饰符检查对于防止某些坏事发生是必不可少的,并且这些检查必须基于编译时类型而不是运行时类型层次结构来执行。(请解释。)
修改后的问题
c.foo() 行的 javac 编译器输出的核心将是这样的指令:
其中 i 是 MyClass 的运行时常量池的索引。该常量池条目将是 CONSTANT_Methodref_info 类型,并且将指示(可能间接地)A)被调用的方法的名称(即 foo),B)方法签名,以及 C)调用该方法的编译时类的名称上(即 MyClass)。
问题是,为什么需要对编译时类型(MyClass)的引用?既然invokevirtual 会在c 的运行时类型上做动态调度,那么存储对编译时类的引用不是多余的吗?
c++ - 带有 body 的纯虚函数的用例?
我最近才知道,在 C++ 中,纯虚函数可以有一个主体。
这些功能的实际用例是什么?