问题标签 [pure-virtual]

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.

0 投票
5 回答
435 浏览

c++ - 如果它不是纯的,则使用虚拟成员函数?

C++03 3.2.2 ...如果对象或非重载函数的名称出现在可能求值的表达式中,则使用该对象或非重载函数。如果它不是纯的,则使用虚拟成员函数...

然后在后面3.2.3我们有:每个程序都应该包含该程序中使用的每个非内联函数或对象的一个​​定义;无需诊断。定义可以显式出现在程序中,可以在标准或用户定义库中找到,或者(在适当时)隐式定义(参见 12.1、12.4 和 12.8)。内联函数应在使用它的每个翻译单元中定义。

按照我正在阅读的内容:不使用纯虚函数。ODR 仅适用于使用的功能。这是否意味着以下内容是合法的?我猜答案是否定的,它没有,但我不明白为什么。

0 投票
5 回答
5877 浏览

c++ - 纯虚函数可能没有内联定义。为什么?

纯虚函数是那些具有纯说明符( = 0;)的虚成员函数

C++03 的第 10.4 条第 2 段告诉我们什么是抽象类,作为旁注,如下:

[注意:函数声明不能​​同时提供纯说明符和定义——尾注] [示例:

——结束示例]

对于那些不太熟悉这个问题的人,请注意纯虚函数可以有定义,但上述条款禁止此类定义出现内联(词法类内)。(对于定义纯虚函数的用途,您可能会看到,例如,这个 GotW

现在对于所有其他种类和类型的函数,它可以提供一个类内定义,而且这个限制乍一看似乎是绝对人为的和莫名其妙的。想想看,第二眼和随后的一瞥似乎都是这样 :) 但我相信如果没有具体原因,限制就不会存在。

我的问题是:有人知道这些具体原因吗?也欢迎好的猜测。

笔记:

  • MSVC 确实允许 PVF 具有内联定义。所以不要惊讶:)
  • 这个问题中的词inline不是指inline关键字。它应该是词汇上的意思
0 投票
2 回答
2284 浏览

c++ - 为什么在尝试使用模板中的纯虚函数构建 C++ 代码时会出现链接器错误?

在我目前正在编写的应用程序中,我创建了一个带有纯虚函数的模板类,然后是另一个类,它继承了前者的实例并实现了虚函数。虚函数是从父构造函数调用的,子构造函数也使用它。由于链接器错误,我无法构建此代码,我不知道为什么。这是重现我遇到的问题的代码的简化版本。

链接器错误在 MSVC 中显示如下:

purevirttest.obj:错误 LNK2019:未解析的外部符号“受保护:虚拟 void __thiscall Foo::echo(void)”(?echo@?$Foo@H@@MAEXXZ) 在函数“public: __thiscall Foo::Foo(int )" (??0?$Foo@H@@QAE@H@Z)

如果我将调用从 Foo 的构造函数移到 echo(),代码构建和执行得很好,我可以毫无问题地调用 bar.echo()。问题是我真的很喜欢构造函数中的那个函数。任何对这个谜团的解释都受到高度赞赏。

0 投票
2 回答
663 浏览

c++ - 这是实现不纯虚函数的合法方式吗?

“不纯虚函数”是指纯虚函数,它们也具有用于诊断目的的实现(如http://www.gotw.ca/gotw/031.htm所述)。

实施它们的犹太方法是:

但这有点乏味,尤其是对于一个类有许多纯虚方法。此外,如果不添加相应的实现,很难确保某人不会意外添加新的纯虚函数。

理想情况下,我想做的是:

但 C++ 标准明确禁止这样做(ISO C++ 2003 标准中的第 10.4/2 节)。

作为替代方案,我想到了以下技巧。在Foo.h标题中:

然后在对应的Foo.cpp源文件中:

以便它获得单个编译的实现。

这样做会合法吗?

0 投票
5 回答
1187 浏览

c++ - C++中的抽象类机制有什么特别之处?

我有几天困扰我的问题。

抽象类是一种特殊类型的类,我们不能实例化,对吧?(通过给至少一个方法声明一个“= 0”来表示/指定,这看起来像是事后的想法)。

抽象类机制为 C++ 带来了哪些“普通”基类无法实现的额外好处?

0 投票
3 回答
25499 浏览

c++ - 什么会导致 C++ 中的纯虚函数调用?

我教了一门 C++ 编程课程,我已经看到了足够多的错误类别,我对如何诊断常见的 C++ 错误有很好的感觉。但是,有一种主要类型的错误我的直觉不是特别好:哪些编程错误会导致调用纯虚函数? 我见过的最常见的错误是从基类构造函数或析构函数调用虚函数。在帮助调试学生代码时,我还应该注意哪些其他事项?

0 投票
3 回答
1897 浏览

c++ - 完全纯虚拟类的 Vtable 放置

根据我对 C++ 规范的(有限)知识,具有虚拟成员的类的 vtable 放置在第一个非纯非内联虚拟方法的定义中。编译器如何处理从具有所有纯虚拟方法(例如接口)的类继承的类?在这种情况下,vtable 放在哪里?

0 投票
3 回答
40125 浏览

c++ - C++的纯虚函数实现和头文件

当有问题的类分为文件时*.h,我在实现从某个抽象类继承的纯虚函数时遇到了一些麻烦。*.cpp编译器(g++)告诉我,由于纯函数的存在,派生类无法实例化。

这是否意味着我必须在接口和接口中声明方法()两次?没有别的办法了吗?*.hderived.h

0 投票
3 回答
2157 浏览

c++ - VS2010 中使用虚函数的 __purecall 问题 - 一旦方法获得纯调用

我有一个非常奇怪的问题:

我使用我的一个基类:IEventlistener(),它被许多其他类实现。大多数情况下,系统都在工作。但是现在出现了一个非常奇怪的问题。

一旦类(CGUIService)实现了接口,一种方法(VGetListenerName)按预期工作,另一种方法(VHandleMessage)在我检查调用堆栈时得到一个纯调用,我不明白为什么-.-(似乎vtable不知何故被覆盖或超出范围...)

我做了一个截图,这样你就可以在我调用 VHandleMessage 之前看到变量,这当然会导致调试断言 R6025 - 纯虚函数调用,因为不知何故,实现的方法没有输入到 IEventlistener() 的 vtable 中。

高分辨率:www.fantasyhaze.com/cb/Error_purecall.png www.fantasyhaze.com/cb/Error_purecall.png

我希望有人能给我一个提示:)

编辑1。)

所以只是为了解释一下,我创建了一个新的屏幕截图,显示了相同的过程,但现在我已经包含了另外 2 个不纯的虚函数并且有一个实现(由于时间原因,我没有时间在使用该接口的每个类中再次实现所有方法)

紫色的是新的,红色的是不起作用的,橙色的是以前的方法,现在有效,现在仍然有效

您可以在左侧看到 VGetListenerName,VHandleEvent1,VHandleEvent2 工作(调试点 + 当前位置)并且这 3 个在 vtable 中......但不是重要的一个(红色)

高分辨率:www.fantasyhaze.com/cb/Error_purecall2.png vtable问题2

编辑2。)

解决方案:

主要问题是,CGUIService 继承自 IBase。为了访问该服务,我使用了一个存储每个服务的服务定位器。因此,它在 Instance Getters Service::GetServiceInstance() 中执行 static_cast,并且还执行了 static_cast 以将服务存储为 IBase。但是 IEventListener 没有在 IBase 中实现,而且服务在没有 IEventListener 的情况下被强制转换回 IBase 并且 vtable 不正常。现在 IBase 实现了 IEventListener 并且它可以工作,因为 static_cast 正确地转换了 IEventListener :)

谢谢你的提示:)

0 投票
4 回答
1099 浏览

c++ - 从构造函数间接调用纯虚函数总是未定义的行为吗?

我正在使用编译器在 AIX上构建CppcheckxlC(请参阅上一个问题)。Checker 类都派生自一个Check类,该类的构造函数将每个对象注册到一个全局列表中:

检查.h

检查缓冲区溢出.h

我似乎遇到的问题与instances().sort()通话有关。sort()将对静态列表中的每个指针调用Check::operator<()which 调用,但刚刚添加到列表中的实例尚未完全运行其构造函数(因为它仍在 inside )。因此,在构造函数完成之前调用这样的指针应该是未定义的行为。Check::name()instances()CheckCheck::Check()->name()CheckBufferOverrun

这真的是未定义的行为,还是我在这里错过了一个微妙之处?

请注意,我不认为调用 tosort()是严格要求的,但效果是 Cppcheck 以确定的顺序运行其所有检查器。这只会影响检测到错误的顺序的输出,这会导致某些测试用例失败,因为它们期望以特定顺序输出。

更新:上述问题仍然(大部分)存在。但是,我认为sort()构造函数中的调用没有引起问题(即通过调用纯虚函数而崩溃)的真正原因Check::operator<(const Check *)sort()! 相反,sort()似乎改为比较指针。这发生在g++xlC中,表明 Cppcheck 代码本身存在问题。