问题标签 [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.

0 投票
2 回答
1624 浏览

c++ - 协变虚函数和智能指针

在 C++ 中,子类可以在重写虚函数时指定不同的返回类型,只要返回类型是原始返回类型的子类(并且两者都作为指针/引用返回)。

是否可以将此功能扩展到智能指针?(假设智能指针是一些模板类)

为了显示:

编辑:正如康拉德鲁道夫建议的那样,这不是直接可能的。但是,我遇到了这种方法:

你会建议走这条路吗?

0 投票
8 回答
13313 浏览

c++ - 为什么虚函数是私有的?

我刚刚在一些代码中发现了这一点:

这有什么目的吗?

(我正在尝试将一些代码从 VS 移植到 G++,这引起了我的注意)

0 投票
8 回答
1775 浏览

c# - 如何避免从基本构造函数调用虚拟方法

我在图书馆中有一个抽象类。我试图尽可能简单地正确实现这个类的派生。问题是我需要在一个三步过程中初始化对象:获取一个文件,执行几个中间步骤,然后使用该文件。第一步和最后一步是派生类特有的。这是一个精简的示例。

当然,麻烦的是构造函数中的虚方法调用。如果不能指望派生类被完全初始化,恐怕图书馆的使用者在使用该类时会发现自己受到限制。

我可以将构造函数中的逻辑拉到受保护的Initialize()方法中,但是实现者可能会直接调用Step1()andStep3()而不是调用Initialize(). 问题的症结在于如果Step2()被跳过不会有明显的错误;在某些情况下只是糟糕的表现。

我觉得无论哪种方式,图书馆的未来用户都必须解决一个严重且不明显的“陷阱”。我应该使用其他一些设计来实现这种初始化吗?

如有必要,我可以提供更多详细信息;我只是想提供一个表达问题的最简单的例子。

0 投票
2 回答
1233 浏览

c++ - 派生、具体、类的 vtables

如果我有一个基类并从中派生 10 个不同的具体派生类,那么每个具体派生类都会有不同的 vtable 吗?

0 投票
3 回答
29197 浏览

php - PHP中虚函数的正确实现?

在我的工作地点(仅限 php),我们有一个用于数据库抽象的基类。当你想向基层添加一个新的数据库表时,你必须创建这个基类的一个子类并重写一些方法来定义使用这个表的个人行为。正常行为应该保持不变。

现在我在我们公司看到了许多新程序员,他们只是重写了默认行为的方法。有些非常“好”,可以放入所有默认行为,并在他们喜欢的地方添加单独的东西,其他人试图使用基类和他们的继承者自杀。

我解决这个问题的第一个想法是考虑应该被继承类覆盖的抽象方法。但除了反对抽象方法的其他论点之外,“抽象”只是没有说明为什么基类不能自己使用以及为什么应该重写这些函数。

经过一番谷歌搜索后,我没有找到在 php 中实现“真正的”虚函数的好答案(只是有一个虚函数,这几乎扼杀了具体实现的所有希望)。

那么,你会怎么处理这件事呢?

0 投票
2 回答
1467 浏览

c++ - 继承自具有虚函数的基类的类的 sizeof

对于以下代码片段。

我似乎注意到的行为是,每当实例化一个空类或从字节边界继承一个空类时,都不会考虑(即:允许大小为 1 字节的对象),在所有其他情况下,对象大小似乎由字节边界。

这是什么原因?我问,因为在这一点上我猜。

0 投票
6 回答
6711 浏览

c++ - C++ 风格:为重写的方法添加前缀 virtual 关键字

我一直在与我的同事讨论是否使用 virtual 关键字作为覆盖方法的前缀,或者仅在原始基类中添加前缀。

我倾向于在所有虚拟方法(即涉及 vtable 查找的方法)前面加上 virtual 关键字。我的理由有三个:

  1. 鉴于 C++ 缺少 override 关键字,virtual 关键字的存在至少通知您该方法涉及查找并且理论上可以被进一步的特化覆盖,或者可以通过指向更高基类的指针来调用。

  2. 始终使用这种风格意味着,当您看到一个没有 virtual 关键字的方法(至少在我们的代码中)时,您最初可以假设它既不是从基类派生的,也不是专门用于子类的。

  3. 如果由于某些错误,从 IFoo 中删除了 virtual,所有子级仍将起作用(CFooSpecialization::DoBar 仍将覆盖 CFooBase::DoBar,而不是简单地隐藏它)。

据我了解,反对这种做法的论点是,“但该方法不是虚拟的”(我认为这是无效的,并且源于对虚拟性的误解),以及“当我看到 virtual 关键字时,我希望意味着有人从中派生,然后去寻找他们。”

假设的类可能分布在多个文件中,并且有几个专业化。

从风格上讲,您会从两个派生类中删除 virtual 关键字吗?如果是这样,为什么?Stack Overflow 的想法是什么?

0 投票
2 回答
3300 浏览

objective-c - 模仿“虚拟功能”的Objective-C协议会产生编译器警告?

在 Objective-C 中,我想强制派生类实现给定接口而不提供默认实现(父类中的实现)。

我知道可以为此使用协议,并且我相信我了解如何使用协议,但我显然遗漏了一些东西......

我已经定义了父类,并从父类派生了几个子类。所有子类都符合需要实现 myMethod 的协议。

我想遍历 Child 实例,通过超类 Parent 引用它们,在每个实例上调用 myMethod。

编译器 - 毫不奇怪 - 警告 Parent 可能不会响应 myMethod。

所有证据都表明 myMethod 实际上会为每个派生的 Child 实例调用,但我收到警告的事实让我感到不安,并表明我没有正确实现这一点。

我错过了什么?

谢谢

0 投票
4 回答
6352 浏览

c++ - 如何在 C++ 构造函数中获得多态行为?

我有一个我想看起来像这样的基类:

重点是强制派生类覆盖I并强制在构造每个对象时调用它。这习惯于做一些簿记,我需要知道正在构造什么类型的对象(但我将当前对象视为基类)。

这不起作用,因为 C++ 不允许您从构造函数调用抽象虚函数。

有没有办法达到同样的效果?


基于这个链接,答案似乎是没有办法得到我想要的。然而它说的是:

最简洁的答案是不。基类对派生自哪个类一无所知——这也是一件好事。[...]也就是说,在构造函数 Derived1::Derived1 开始之前,该对象不会正式成为 Derived1 的实例。

但是在我的情况下,我不想知道它什么,而是它会变成什么。事实上,只要用户可以(事后)将它映射到一个类,我什至不在乎我得到了什么。所以我什至可以使用返回指针之类的东西并摆脱它。

(现在回到阅读该链接)

0 投票
4 回答
5000 浏览

c++ - Template class + virtual function = must implement?

This code:

is easily compiled without any complaints, as long as I never call a.DoSomething().

However, if I define DoSomething as a virtual function, I will get a compile error saying that B doesn't declare SomeFunction. I can somewhat see why it happens (DoSomething should now have an entry in the vtable), but I can't help feeling that it's not really obligated. Plus it sucks.

Is there any way to overcome this?

EDIT 2: Okay. I hope this time it makes sence: Let's say I am doing intrusive ref count, so all entities must inherit from base class Object. How can I suuport primitive types too? I can define:

so I can use Primitive<int>, Primitive<char>... But how about Primitive<float>? It seems like a problem, because floats don't have a %= operator. But actually, it isn't, since I'll never call operator %= on Primitive<float>. That's one of the deliberate features of templates.

If, for some reason, I would define operator %= as virtual. Or, if i'll pre-export Primitive<float> from a dll to avoid link errors, the compiler will complain even if I never call operator %= on a Primitive<float>. If it would just have fill in a dummy value for operator %= in Primitive<float>'s vtable (that raises an exception?), everything would have been fine.