来自我在上一个问题中的评论:
由于不能有抽象类的实例,因此在重载解析后永远不能选择纯虚函数
明显的反应是:
abstract_class* a = new derived_class; a->pure_virtual_function();
以及正确性的最佳证明:
动态调度在运行时发生,基于当时实际使用的对象。重载解析在编译时发生。
然而令我烦恼的是,当在我们的情况下明确地解析类成员的范围时,编译失败,所以看起来pure virtual function
从未通过重载解析实际选择:< / p>
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&amp;)'
这里的情况是什么,如果在重载决策中实际选择了纯虚函数,为什么我不能“强迫”编译器执行相同的操作(如解析所做的那样)。
答案 0 :(得分:2)
可以通过重载分辨率选择纯虚函数。在大多数情况下,它不会被调用。它的最终覆盖将被调用,就像任何其他虚函数一样。
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()
并由虚拟调度机制调用。纯度与此无关。
答案 1 :(得分:1)
如果我理解,你真的有两个问题。两者都在这里解决:
失败是因为您明确尝试调用没有实现的纯虚函数。但是,可以实现纯虚函数。这是一个单行实现,它将使您的代码成功编译并运行:
void B::copy(B const& rhs) { std::cout << "I am pure and virtuous\n"; }
总之,不,不是在这种情况下。但是有一种情况是必须实现纯虚函数并且将被调用(但严格来说,不是由于重载决议)。那种情况是存在基类的纯虚析构函数。有关原因和方式的详细信息,请参阅this SO question。
但是,可以在重载决策中选择纯虚函数 。将其添加到B
void B::copy(B const& rhs) const { std::cout
<< "I am pure and virtuous and constant\n"; }
D
中的相应功能:
void copy(B const& rhs) const { /* do nothing */ }
您会发现重载分辨率只会导致“我纯洁而善良”。