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

时间:2014-05-03 12:36:25

标签: c++

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


纯虚函数

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 ++ newb,但不是编程新手)。

1 个答案:

答案 0 :(得分:6)

它们具有完全不同的用途,因此您不应该对它们进行相同的处理或尝试对它们进行比较。


纯虚方法意味着派生类必须实现该方法本身才能完成。这通常会像这样使用:

<强> 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,并知道它们将具有use功能。

E.g。

<强>的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

E.g。

<强>的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

这使得构建时间变得更短。