在C++中使用类外定义的纯虚函数?

在C++中使用类外定义的纯虚函数?,c++,C++,我在互联网上读到,我们很少会定义函数,即使它在类中定义为纯虚拟函数,如下所示 class abc { public: virtual void func() = 0; } void abc::func() { cout << "in abc::func()"; } 我不明白这有什么用。在链接中,有人提到我们可以将其用作纯虚拟析构函数。但我还不清楚。任何人都可以告诉我它的用途。析构函数需要一个实现,即使它是纯虚拟的,因为析构函数是在每个基类链上自动和

我在互联网上读到,我们很少会定义函数,即使它在类中定义为纯虚拟函数,如下所示

class abc
{
    public:
        virtual void func() = 0;
}

void abc::func()
{
    cout << "in abc::func()";
}

我不明白这有什么用。在链接中,有人提到我们可以将其用作纯虚拟析构函数。但我还不清楚。任何人都可以告诉我它的用途。

析构函数需要一个实现,即使它是纯虚拟的,因为析构函数是在每个基类链上自动和非虚拟地调用的


因此,如果你有一个纯虚拟析构函数,你最好也定义它

否则,您将无法销毁该类或从该类派生的类的任何对象:将在销毁中尝试析构函数调用,并且链接器将抱怨它找不到定义


由于一种从未被修正过的语法怪癖,该定义不能在类定义中内联提供,但必须单独提供。

析构函数需要一个实现,即使它是纯虚拟的,因为析构函数是在每个基类链上自动和非虚拟地调用的


因此,如果你有一个纯虚拟析构函数,你最好也定义它

否则,您将无法销毁该类或从该类派生的类的任何对象:将在销毁中尝试析构函数调用,并且链接器将抱怨它找不到定义


由于语法上的一个怪癖,该定义无法在类定义中内联提供,但必须单独提供。

没有规则阻止您定义纯虚拟方法。这可以用来强制子类提供实现,但同时也让您有机会提供方便的实现以及执行常见任务

例如,如果xyz源于abc,则可以在其自身中使用abcs函数定义:

struct xyz : public abc
{
    virtual void func() override
    {
        abc::func(); // explicitely calling the implementation provided by abc
    }
}

没有规则阻止您定义纯虚拟方法。这可以用来强制子类提供实现,但同时也让您有机会提供方便的实现以及执行常见任务

例如,如果xyz源于abc,则可以在其自身中使用abcs函数定义:

struct xyz : public abc
{
    virtual void func() override
    {
        abc::func(); // explicitely calling the implementation provided by abc
    }
}

实现的纯虚函数的另一个用途是强制子类显式地请求默认行为。有效的C++项目34给出了一个很好的例子?
class Airplane
{
public:
    virtual void fly() = 0;
};

Airplane::fly()
{
    //A default implementation
}

class ModelA : public Airplane
{
public:
    virtual void fly() { Airplane::fly(); } //explicitly use the default
};

class ModelB : public Airplane
{
public:
    virtual void fly() { Airplane::fly(); } //explicitly use the default
};

class ModelC : public Airplane
{
public:
    virtual void fly() { //different implementation }
};

这样做的目的是让客户机很难意外地继承默认行为,如果他们考虑到这一点的话,他们可能不希望这样做。更一般地说,这个习惯用法有助于通过分解虚拟方法的实现来避免代码重复,这些方法本质上不是默认的。

实现的纯虚拟函数的另一个用途是强制子类显式地请求默认行为。有效的C++项目34给出了一个很好的例子?
class Airplane
{
public:
    virtual void fly() = 0;
};

Airplane::fly()
{
    //A default implementation
}

class ModelA : public Airplane
{
public:
    virtual void fly() { Airplane::fly(); } //explicitly use the default
};

class ModelB : public Airplane
{
public:
    virtual void fly() { Airplane::fly(); } //explicitly use the default
};

class ModelC : public Airplane
{
public:
    virtual void fly() { //different implementation }
};

这样做的目的是让客户机很难意外地继承默认行为,如果他们考虑到这一点的话,他们可能不希望这样做。更一般地说,这个习惯用法有助于通过分解虚拟方法的实现来避免代码重复,这些虚拟方法本质上不是默认的。

答案在链接中:如果您想阻止其他人实例化您的类,那么它很有用。就我个人而言,我认为有更好的方法可以做到这一点,例如,将构造函数声明为private。@巴拉克·马诺斯:的确,尽管一个简单的定义private-public会破坏它that@StealthyHunter7是的,而且simpel系列会破坏你的标准合规性,很可能会破坏你的整体project@StealthyHunter7:哈哈,你可以把它作为一个单独的问题贴在这里。。。比如说,究竟为什么有人要定义“公私”,或者定义“公私”可能有什么好处?答案可能是什么都没有!+对你的问题投了几票反对票。@barak manos:事实上有一个案例,有人在做项目时使用了它,而构建API的团队还没有完成,因此,他们没有直接使用接口,而是直接使用私有成员。答案在链接中:如果你想阻止其他人实例化你的类,这很有用。就我个人而言,我认为有更好的方法可以做到这一点,例如,将构造函数声明为private。@巴拉克·马诺斯:的确,尽管一个简单的定义private-public会破坏它that@StealthyHunter7是的,而且simpel系列会破坏你的标准合规性,很可能会破坏你的整体project@StealthyHunter7:哈哈,你可以把它作为一个单独的问题贴在这里。。。比如说,究竟为什么有人要定义“公私”,或者定义“公私”可能有什么好处?答案可能是什么都没有!+对你的问题投了几票反对票。@barak manos:事实上
有人在做项目时使用了它,而构建API的团队还没有完成,因此,他们没有直接使用接口,而是直接使用私有成员。因此,如果你有一个纯虚拟析构函数,并不能完全回答为什么你要从一个纯虚拟析构函数开始的问题…@barakmanos:通常的pat短语是当你想将一个类抽象,并且没有其他好的选择时。但这只是把问题推向了一边。究竟为什么有人会这样想。我隐约记得我曾经知道一些例子。我现在想不起来了,所以这不是你每天都需要的东西,甚至不是每周、每月或每年都需要的东西。我理解并同意,但我认为OP是在问为什么,就像为什么需要它一样。我看着它,仍然找不到答案:析构函数需要一个实现,即使它是纯虚拟的-好吧,但为什么一开始它是纯虚拟的?因此,如果你有一个纯虚拟析构函数,你最好也定义它-那么为什么我应该有一个纯虚拟析构函数呢?使类抽象。嗯,似曾相识。好的,抽象在这里的意思是不可实例化的,除了作为基类。因此,如果你有一个纯虚拟析构函数,并不能很好地回答为什么你要从一个纯虚拟析构函数开始…@barakmanos:通常的pat短语是当你想将一个类抽象,并且没有其他好的选择时。但这只是把问题推向了一边。究竟为什么有人会这样想。我隐约记得我曾经知道一些例子。我现在想不起来了,所以这不是你每天都需要的东西,甚至不是每周、每月或每年都需要的东西。我理解并同意,但我认为OP是在问为什么,就像为什么需要它一样。我看着它,仍然找不到答案:析构函数需要一个实现,即使它是纯虚拟的-好吧,但为什么一开始它是纯虚拟的?因此,如果你有一个纯虚拟析构函数,你最好也定义它-那么为什么我应该有一个纯虚拟析构函数呢?使类抽象。嗯,似曾相识。好的,这里的抽象表示不可实例化,基类除外。我认为这不是一个好的做法,因为它允许客户端代码调用默认处理,这可能不适合派生类实例。相反,将默认值设为一个受保护的函数,separate.@Alf,很好的观点,以及我在实践中可能会如何实现它。我认为在某些情况下,这种行为是可以接受的,但我想不出有哪一种不能以更清晰的方式实现。我认为这不是一种好的做法,因为它允许客户端代码调用默认处理,这可能不适合派生类实例。相反,将默认值设为一个受保护的函数,separate.@Alf,很好的观点,以及我在实践中可能会如何实现它。我认为在某些情况下,这种行为是可以接受的,但我想不出有哪种情况不能在我脑海中以更清晰的方式实施。