纯虚函数与身体的用例?

mis*_*tor 47 c++ virtual-functions

我最近才知道,在C++中,纯虚函数可以选择有一个体.

这些功能的实际用例是什么?

sbi*_*sbi 43

经典是一个纯粹的虚拟析构函数:

class abstract {
  public: 
    virtual ~abstract() = 0;
};

abstract::~abstract() {}
Run Code Online (Sandbox Code Playgroud)

你把它变成纯粹的,因为没有别的东西可以这样做,你希望这个类是抽象的,但你必须提供一个实现,因为派生类的析构函数明确地调用你的.是的,我知道,这是一本非常愚蠢的教科书例子,但同样这是一部经典之作.它必须出现在第一版的C++编程语言中.

无论如何,我记不起真的需要能够实现纯虚函数.对我而言,这个功能的唯一原因似乎是因为它必须明确禁止,而Stroustrup没有找到原因.

如果您觉得自己需要这个功能,那么您的设计可能就错了.

  • downvoter可能有的一个问题(对于记录,我没有downvote)是没有强有力的理由拥有纯虚拟析构函数.如果还有另一个纯虚函数,那么dtor就没有理由是纯虚拟的(虽然它几乎肯定应该是虚拟的).如果dtor是唯一的纯虚函数,则实际上可能不需要该类是抽象的. (3认同)

Bri*_*ndy 37

带或不带主体的纯虚函数只是意味着派生类型必须提供自己的实现.

如果派生类要调用基类实现,则基类中的纯虚函数体很有用.


Mic*_*urr 17

抽象基类(具有纯虚函数)可能为其声明的纯虚函数提供实现的一个原因是让派生类具有他们可以选择使用的简单"默认".对于可以选择性覆盖的普通虚函数来说,这没有很多优势 - 实际上,唯一真正的区别在于你强迫派生类明确使用'默认'基类实现:

class foo {
public:
    virtual int interface();
};

int foo::interface() 
{
    printf( "default foo::interface() called\n");
    return 0;
};


class pure_foo {
public:
    virtual int interface() = 0;
};

int pure_foo::interface()
{
    printf( "default pure_foo::interface() called\n");
    return 42;
}

//------------------------------------

class foobar : public foo {
    // no need to override to get default behavior
};

class foobar2 : public pure_foo {
public:
    // need to be explicit about the override, even to get default behavior
    virtual int interface();
};

int foobar2::interface()
{
    // foobar is lazy; it'll just use pure_foo's default
    return pure_foo::interface();
}
Run Code Online (Sandbox Code Playgroud)

我不确定是否有很多好处 - 也许在设计从抽象类开始的情况下,然后随着时间的推移发现很多派生的具体类都在实现相同的行为,所以他们决定改变这种行为到纯虚函数的基类实现.

我认为将普通行为放入纯虚函数的基类实现中可能也是合理的,派生类可能需要修改/增强/扩充.


sho*_*osh 8

一个用例是从类的构造函数或析构函数中调用纯虚函数.

  • @John:我读的不同了.但是,无论如何,我认为从ctors或detors调用虚拟函数,无论是否纯粹,都是一个非常值得怀疑的做法. (3认同)

Ofe*_*lon 8

全能的Herb Sutter,C++标准委员会的前任主席,确实提供了3个场景,您可以考虑为纯虚拟方法提供实现.

不得不亲自说 - 我发现它们都没有说服力,并且通常认为这是C++的语义瑕疵之一.似乎C++不遗余力地构建和拆除抽象父级vtable,而不是仅仅在子项构建/破坏期间简要地暴露它们,然后社区专家一致建议永远不要使用它们.

  • Sutter的文章很棒.为我清理了一些晦涩难懂的想法. (2认同)