代码之家  ›  专栏  ›  技术社区  ›  Tobias

在什么情况下,给出纯虚函数的实现是有利的?

  •  28
  • Tobias  · 技术社区  · 15 年前

    在C++中,给出纯虚拟函数的实现是合法的:

    class C
    {
    public:
      virtual int f() = 0;
    };
    
    int C::f() 
    {
      return 0;
    }
    

    你为什么要这样做?

    相关问题: C++ faq lite 包含一个示例:

    class Funct {
    public:
      virtual int doit(int x) = 0;
      virtual ~Funct() = 0;
    };
    
    inline Funct::~Funct() { }  // defined even though it's pure virtual; it's faster this way; trust me
    

    我不明白为什么这个析构函数被声明为纯虚拟的,然后被实现;我也不明白为什么这个声明应该更快。

    6 回复  |  直到 13 年前
        1
  •  23
  •   CB Bailey    15 年前

    声明的析构函数必须始终实现,因为实现将调用它们作为派生对象销毁的一部分。

    如果其他纯虚拟函数提供有用的公共功能,但总是需要专门化,则可以实现它们。在这种情况下,通常派生类实现将对基本实现进行显式调用:

    void Derived::f()
    {
        Base::f();
    
        // Other Derived specific functionality
    }
    

    通常,如果需要使类抽象(即防止创建非派生实例),则将析构函数设为虚拟的,但该类没有其他自然纯虚拟的函数。我认为“相信我它更快”是指这样一个事实:因为作为派生对象清理的一部分调用的析构函数不需要使用vtable查找机制,所以可以利用内联实现,这与典型的虚拟函数调用不同。

        2
  •  4
  •   Loki Astari    15 年前

    如果您具有派生类可以使用的公共功能。 但他们也需要做其他工作。

    因此,派生类实现了虚函数并调用基础基础基础版本:

    class X: public C
    {
        public:
            virtual int f()
            {
                return C::f() + 1; // I am +1 over my parent.
            }
    };
    
        3
  •  4
  •   Tobias    15 年前

    刚刚发现赫伯·萨特在他的书中回答了这个问题的第一部分。 Guru of the Week #31 .

        4
  •  2
  •   Rob Wells    15 年前

    G'Day.

    关于为基类中声明的成员函数提供默认实现,我现在能想到的唯一原因是,您希望在哪里提供行为的默认实现,作为对基类专门化的人的可能实现选择。

    派生类的作者可以选择使用基类作者提供的默认实现,而不是添加自己的专门实现。

    通常情况下,人们反对拥有单独的函数来提供接口和行为的默认实现,但他们仍然希望在默认实现和关联接口之间分离。

    啊,刚才看到了@martin york的帖子,它提供了一个例子。

    实际上,Scott Meyers在他的《有效C++》一书中对此进行了讨论。这是第一版的第36项。

    高温高压

    干杯,

        5
  •  0
  •   ralphtheninja    15 年前

    因为写东西被认为是不正确的:

    class Funct {
    public:
      virtual int doit(int x) = 0;
      virtual ~Funct() = 0 {};
    };
    

    如果从此类派生,则仍将调用析构函数。声明所有方法纯虚拟只是为了清晰起见。你不妨这样写:

    class Funct {
    public:
      virtual int doit(int x) = 0;
      virtual ~Funct() {};
    };
    

    类仍然是抽象的,因为至少有一个方法是纯虚拟的。析构函数仍然是内联的。

        6
  •  0
  •   Community kfsone    7 年前

    关于虚拟析构函数的速度,这是因为析构函数是在cpp文件中定义的,而不是头文件中定义的。它与大小的关系比速度的关系更大。对“大型C++软件设计”进行了详细的说明。不幸的是,我无法记住所有的细节,但我认为内联虚拟函数在vtable中被定义了多次。

    这里有一个讨论: Are inline virtual functions really a non-sense?