理解纯虚拟函数
Understanding pure-virtual functions
以下代码编译良好:
struct A
{
const int a;
virtual void foo() = 0;
};
struct B : A{ };
void A::foo(){ std::cout << "foo" << std::endl; }
演示
问题是结构体A
是一个抽象体,因此我们不能实例化它。但我们可以将它和进行子类化
struct A
{
const int a;
virtual void foo() = 0;
};
struct B : A{ };
void A::foo(){ std::cout << "foo" << std::endl; }
int main(int argc, char ** argv)
{
B b;
b.foo(); //error: implement pure-virtual
}
演示
仍然不能使用A
对foo
的实现,我怀疑它永远不会被调用。所以,我不知道这个定义的应用。。。是的,提供虚拟析构函数的定义是有用的,但事实并非如此。
纯虚拟的定义在哪里可以使用?
您可以显式调用它。
struct A
{
const int a;
virtual void foo() = 0;
};
struct B : A
{
void foo();
};
void A::foo()
{
std::cout << "A::foo" << std::endl;
}
void B::foo()
{
A::foo(); // here
std::cout << "B::foo" << std::endl;
}
int main(int argc, char ** argv)
{
B b;
b.foo(); // prints A::foo followed by B::foo
}
但是您可以(并且必须)实现(如果B是可实例化的)A的void foo()
的重写。该实现可以(但绝对不需要)调用BASE实现:
struct B : public A
{
virtual void foo() {A::foo();}
};
我已经实现了这个场景,其中我有一个非常简单的"基础"实现,但要求所有叶通过链接回这个通用实现来主动决定是否使用这个基础。
您可以从B
中调用它。由于A::foo()
是纯虚拟的,B
需要定义foo:
struct A {
virtual void foo() = 0;
};
void A::foo(){ std::cout << "A::foo() ran" << std::endl; }
struct B : A {
void foo() {
A::foo(); // <--
std::cout << "B::foo() ran" << std::endl;
}
};
int main(int argc, char ** argv)
{
B b;
b.foo();
}
这就是在C++中实现接口的方法。您强制子类实现要实例化的方法,并在该抽象基类上的自己的代码中进行多态操作,将特定实现留给接口的客户端。
就基类中的实现而言,我只能想到两个原因。第一,允许它们不必使用特殊情况下的析构函数。第二,B可以根据A::foo()、IE(默认实现)定义自己的实现。
相关文章:
- C++无法定义虚拟函数 OUTER 类和头文件
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 尝试将unique_ptrs推送到向量时使用纯虚拟函数错误
- 有没有比在库中添加一个并非由所有派生类实现的新虚拟函数更好的设计实践
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- 当覆盖存在时调用基本虚拟"binded to object"函数
- 如何在C++中伪造虚拟可变参数函数模板?
- 类型擦除的std::function与虚拟函数调用的开销
- 重写虚拟函数和继承
- 是否可以使用函数指针调用虚拟析构函数?
- 在没有动态内存的世界中,我是否需要虚拟析构函数?
- 虚拟继承基构造函数消除
- "虚拟""覆盖"析构函数
- 类中的虚拟布尔函数参数不起作用
- 用纯虚拟函数兜圈子
- 将C++子类成员函数(虚拟实现)传递给 C 类型函数指针
- 尝试在 QLabel 上绘画失败(无法在没有对象的情况下调用成员函数"虚拟无效 QLabel::p aintEvent(QPaintEvent*)")
- 声明析构函数虚拟就足够了吗?
- 视觉 C++当我们在基类中使函数成为纯虚拟时,那么在子类中再次使相同的函数虚拟的必要性是什么
- 重载函数(虚拟/非虚拟)