实现纯虚函数的必要性是什么
what's the necessity of the implementation of a pure virtual function
纯虚拟函数是抽象基类的必备属性。因此,不应该进行任何实现,这是非常直观的理解。但最近我发现,纯虚拟函数仍然可以在以后定义并静态调用(而不是由对象实例调用)。我想不出这样做的原因。如果一个虚拟函数被定义为纯函数,那么实现它的原因是什么?
class A{
public:
...
virtual void interface() = 0; //Pure Virtual functions
...
}
void A::interface() //Implementation
{
cout<<"This the implementation for A interface";
}
我很好奇这背后的逻辑。为什么c++是这样设计的?
有一个"默认"实现可能是有意义的,如果对具体类有用,可以使用它。他们仍然需要覆盖它,但可以非虚拟地调用基类版本:
struct B : A {
void interface() {
A::interface(); // call the default implementation
// and maybe do some B-specific things too
}
};
我想不出这样做的原因。如果一个虚拟函数被定义为纯函数,那么实现它的原因是什么?
纯虚拟函数的目的是而不是禁止定义。这是为了将类标记为不可实例化。
提供一个定义可能有助于派生类:
struct A
{
virtual void foo() = 0;
};
void A::foo()
{
/* some common logic here */
}
struct B : A
{
virtual void foo() overrides
{
bar();
A::foo();
}
void bar();
};
struct C : A
{
virtual void foo() overrides
{
baz();
A::foo();
}
void baz();
};
纯虚拟函数只是意味着该函数必须被所有派生类覆盖——这并不意味着该功能不能/不应该有自己的实现。这种纯虚拟函数实现的两个最明显的例子是:
- 派生类实现可以调用基类实现
- 有时你会希望基类是抽象的,但在这种情况下,没有任何方法可以标记为纯
virtual
,析构函数是最明显的选择,但在这样的析构函数中仍然需要实现
interface()=0表示派生类必须提供实现,因此定义影响派生类,但允许基类实现该方法,以便派生类始终可以调用base::interface()。
您显然完全误解了术语"静态"在本文中的含义。
是的,纯虚拟函数仍然可以有实体,即它们仍然可以被定义。
不,您不能在"没有对象实例"的情况下调用这样的函数,正如您似乎错误地认为的那样。带有实体的纯虚拟函数仍然是非静态成员函数。它仍然需要调用一个对象实例。
当有人说可以"静态"调用这样的函数时,这意味着可以直接调用它,而不使用虚拟调度机制。经过虚拟调度的函数调用有时被称为"虚拟调用"或"动态调用",而直接函数调用有时则被称为"静态调用"。在此上下文中,术语"静态"具有完全不同的含义,与静态成员函数没有任何联系。
在C++语言中,直接的非虚拟(即"静态")调用可以通过在调用中指定限定成员名来显式执行。例如,如果类B
派生自类A
,那么在某些方法B::foo()
中,可以使用以下语法
void B::foo() {
A::interface(); // <- qualified method name
}
它直接调用您提供的CCD_ 5的实现。对于B
类型的对象b
,可以执行与相同类型的调用
B b;
b.A::interface(); // <- qualified method name
在这两种情况下,调用都是针对特定对象执行的(第一个示例中为*this
,第二个示例为b
)。
当派生类的析构函数调用基类的析构因子时,几乎同样的事情也会隐式发生,这就是为什么你经常会在纯虚拟析构函数中遇到这种情况(即它们被声明为纯虚拟的,但有一个主体)。
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- C++避免重复声明的语法是什么
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- C++从另一个类访问公共静态向量的正确方法是什么
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- C++中名称篡改的目的是什么
- 在 c++ 中拥有一组结构的正确方法是什么?
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 是什么阻止DOMTimerCoordinator::NextID进入无休止的循环
- 派生类销毁的最佳实践是什么
- 这个语法std::class<>{}(arg1, arg2) 在C++中是什么意思?
- 通过JNI传递数据数组的最快方法是什么
- "using namespace std;"在C++的作用是什么?
- 当我们已经有 char[] 时,在 c++ 中字符串的必要性是什么?
- 在此C 代码中指针的必要性是什么?
- 在类映射中,当我们有迭代器时,constiterator的必要性是什么
- 实现纯虚函数的必要性是什么
- 视觉 C++当我们在基类中使函数成为纯虚拟时,那么在子类中再次使相同的函数虚拟的必要性是什么
- const关键字的必要性是什么