头文件中未定义方法和纯虚方法的区别

Difference between undefined methods and pure virtual methods in a header file

本文关键字:方法 区别 未定义 文件      更新时间:2023-10-16

使用带纯虚方法的类声明比使用带未定义成员的类声明有什么优点或缺点?例子:


纯虚函数

TestClass.h

namespace test {
    class TestClass {
        virtual void DoSomething() = 0;
    }
}

TestClass.cpp

namespace test {
    class TestClassImpl : public TestClass {
        void DoSomething() {
            std::cout << "Hello!" << std::endl;
        }
    }
}

未定义的方法

TestClass.h

namespace test {
    class TestClass {
        void DoSomething();
    }
}

TestClass.cpp

namespace test {
    void TestClass::DoSomething() {
        std::cout << "Hello!" << std::endl;
    }
}

我知道c++中的虚函数调用由于间接和额外的分支而有开销,但现在这些开销与我无关。我更感兴趣的是拥有可扩展的,正确的代码(供参考:我是一个c++新手,但不是一个编程新手)。

它们有完全不同的用途,因此您不应该将它们等同对待或试图比较它们。


纯虚方法意味着派生类必须自己实现该方法才能使其完整。这通常像这样使用:

Object.hpp

class Object{
    public:
        virtual void use() = 0;
};
class Banana: public Object{
    public:
        void use(){std::cout << "You ate the Banana! Good work." << std::endl;}
};
class Rock: public Object{
    public:
        void use(){std::cout << "You use the Rock. Nothing happens." << std::endl;}
};

以便以后您可以将RockBanana的实例称为Object s,并知道它们将具有use功能。

main.cpp

#include "Object.hpp"
int main(){
    std::vector<Object*> objects;
    Banana banana;
    Rock rock;
    objects.push_back(&banana);
    objects.push_back(&rock);
    for(const Object *o : objects)
        o->use();
}

如果您决定不使用虚函数,那么您就不能将对象本身视为Object

main.cpp

class Banana{
    public:
        void use();
};
class Rock{
    public:
        void use();
};
int main(){
    std::vector<???> objects;
    Banana banana;
    Rock rock;
    objects.push_back(&banana); // can't do
    objects.push_back(&rock); // or this
    for(const ??? *o : objects)
        o->use(); // and definitely not this
}

如果你试图通过将函数的实现委托给不同的代码单元来做到这一点,那么,我不知道你将试图做什么。

你可以在另一个文件中实现你的虚函数,只要你实现了它们;否则,当试图访问这种类型的对象作为Object,你会得到错误。


在处理库和非常大的项目时,您可能希望使用带有外部实现的函数。这样做是为了在每次翻译代码时不必再次编译该函数,只需调用已经实现的代码:D