是在重载解析中实际选择的纯虚函数
Is a pure virtual function actually selected in overload resolution?
摘自我对上一个问题的评论:
由于不能有抽象类的实例,因此在重载解析之后永远不能选择纯虚函数
明显的反应是:
abstract_class* a = new derived_class; a->pure_virtual_function();
和最好的正确性证明:
动态分派发生在运行时,基于当时实际使用的对象。重载解析在编译时发生。
然而,令我困扰的是,当显式解析类成员的作用域时,在我们的案例编译中,失败了,所以看起来pure virtual function
实际上从未通过重载解析被选中:
struct B
{
virtual void copy(B const& rhs) = 0;
};
struct D : B
{
void copy(B const& rhs)
{
D const *pd = dynamic_cast<D const*>(&rhs);
if (pd) {
y = pd->y;
}
}
int y;
};
int main()
{
D d1, d2;
d1.y = 2;
d2.y = 5;
B *p1(&d1), *p2(&d2);
////////////////////////////////////////////
(*p1).B::copy(*p2);
////////////////////////////////////////////
return 0;
}
错误消息对' B::copy(B const&)'的未定义引用
对' B::copy(B const&)'的未定义引用
这里的情况是什么,如果纯虚函数实际上是在重载解析中选择的,为什么我不能"强制"编译器做同样的事情(就像解析一样)
可以通过重载解析选择纯虚函数。在大多数情况下,它不会被调用。它的最终重写将被调用,就像其他虚函数一样。
struct A
{
virtual void foo() = 0;
void foo(int);
};
A* getA();
int main ()
{
A* a = getA();
a->foo();
}
struct B : A
{
void foo() {}
};
A* getA()
{
return new B;
}
重载解析在编译时选择A::a()
(而不是 B::a()
),然后在运行时通过虚拟调度机制找到B::a()
并调用。纯度在这里无关紧要
如果我没理解错的话,你其实有两个问题。这两个地址都在这里:
为什么编译失败?
失败是因为您显式地尝试调用没有实现的纯虚函数。但是,可以实现纯虚函数。下面是一个单行实现,它将使您的代码成功编译并运行:
void B::copy(B const& rhs) { std::cout << "I am pure and virtuousn"; }
是否在重载解析中实际选择了纯虚函数?
总之,不,不是在这种情况下。但是有一种情况,纯虚函数必须实现,并且将被调用(但严格地说,不是由于重载解析)。这种情况发生在基类存在纯虚析构函数的情况下。
但是,在重载解析中可以选择纯虚函数。添加到B
void B::copy(B const& rhs) const { std::cout
<< "I am pure and virtuous and constantn"; }
和D
中相应的函数:
void copy(B const& rhs) const { /* do nothing */ }
你会发现重载解析只会导致"I am pure and virtuous"被打印。
相关文章:
- 如何基于循环迭代器选择函数
- 控件不会在选择函数旁边移动
- 函数模板 - 使用同一类型调用时,使用不同的参数类型选择函数
- 使用声明类型选择函数专业化
- 如何使“确认选择”函数从“主要”取消,如果它是假的
- 在编译时根据参数大小选择函数
- 在选择函数中检测超时的客户端
- 如何选择函数模板专用化
- 如何编写用于选择函数的样板代码
- "string_literal"解析为布尔值,但不解析为 std::string,当编译器选择函数的重载版本时
- 如何在编译时根据 constexpr 结果选择函数
- 使用模板选择函数的正确版本
- 在选择函数中等待fd的异常条件是什么?
- 矢量扩展的最佳选择函数
- 根据运行时数据选择函数重载
- 选择函数一直返回-1
- 在运行时选择函数参数
- 使用SFINAE根据函数是否存在特定的过载来选择函数
- 如何在c++中使用namespace::function选择函数的单个重载
- 根据模板参数选择函数名称