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

C++ 头文件中未定义方法和纯虚拟方法之间的区别,c++,C++,与使用未定义成员的类声明相比,使用纯虚拟方法的类声明有哪些优点或缺点?例如: 纯虚函数 TestClass.h namespace test { class TestClass { virtual void DoSomething() = 0; } } namespace test { class TestClass { void DoSomething(); } } TestClass.cpp namespace test

与使用未定义成员的类声明相比,使用纯虚拟方法的类声明有哪些优点或缺点?例如:


纯虚函数 TestClass.h

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

namespace test {
    class TestClassImpl : public TestClass {
        void DoSomething() {
            std::cout << "Hello!" << std::endl;
        }
    }
}
namespace test {
    void TestClass::DoSomething() {
        std::cout << "Hello!" << std::endl;
    }
}
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;}
};
#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();
}
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
}
TestClass.cpp

namespace test {
    class TestClassImpl : public TestClass {
        void DoSomething() {
            std::cout << "Hello!" << std::endl;
        }
    }
}
namespace test {
    void TestClass::DoSomething() {
        std::cout << "Hello!" << std::endl;
    }
}
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;}
};
#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();
}
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
}
名称空间测试{
void TestClass::DoSomething(){

std::cout它们有完全不同的用途,因此你不应该对它们一视同仁或试图进行比较


纯虚拟方法意味着派生类必须实现该方法本身才能使其完整。这通常是这样使用的:

Object.hpp

namespace test {
    class TestClassImpl : public TestClass {
        void DoSomething() {
            std::cout << "Hello!" << std::endl;
        }
    }
}
namespace test {
    void TestClass::DoSomething() {
        std::cout << "Hello!" << std::endl;
    }
}
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;}
};
#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();
}
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
s

例如

main.cpp

namespace test {
    class TestClassImpl : public TestClass {
        void DoSomething() {
            std::cout << "Hello!" << std::endl;
        }
    }
}
namespace test {
    void TestClass::DoSomething() {
        std::cout << "Hello!" << std::endl;
    }
}
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;}
};
#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();
}
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
}
class香蕉{
公众:
无效使用();
};
阶级摇滚{
公众:
无效使用();
};
int main(){
向量对象;
香蕉;
岩石;
objects.push_back(&banana);//不行
objects.push_back(&rock);//或者这个
用于(常数???*o:对象)
o->use();//当然不是这个
}
如果您试图通过将函数的实现委托给不同的代码单元来实现这一点,那么,我不知道您将尝试做什么

实际上,您可以在另一个文件中实现虚拟函数,只要您确实实现了它们;否则,当您尝试以
对象
的形式访问此类对象时,将出现错误


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


这使得构建时间更短。

它们有完全不同的用途,因此您不应该对它们一视同仁或试图进行比较


纯虚拟方法意味着派生类必须实现该方法本身才能使其完整。这通常是这样使用的:

Object.hpp

namespace test {
    class TestClassImpl : public TestClass {
        void DoSomething() {
            std::cout << "Hello!" << std::endl;
        }
    }
}
namespace test {
    void TestClass::DoSomething() {
        std::cout << "Hello!" << std::endl;
    }
}
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;}
};
#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();
}
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
s

例如

main.cpp

namespace test {
    class TestClassImpl : public TestClass {
        void DoSomething() {
            std::cout << "Hello!" << std::endl;
        }
    }
}
namespace test {
    void TestClass::DoSomething() {
        std::cout << "Hello!" << std::endl;
    }
}
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;}
};
#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();
}
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
}
class香蕉{
公众:
无效使用();
};
阶级摇滚{
公众:
无效使用();
};
int main(){
向量对象;
香蕉;
岩石;
objects.push_back(&banana);//不行
objects.push_back(&rock);//或者这个
用于(常数???*o:对象)
o->use();//当然不是这个
}
如果您试图通过将函数的实现委托给不同的代码单元来实现这一点,那么,我不知道您将尝试做什么

实际上,您可以在另一个文件中实现虚拟函数,只要您确实实现了它们;否则,当您尝试以
对象
的形式访问此类对象时,将出现错误


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


这会缩短hella的构建时间。

此处未定义哪个方法?@RakibulHasan我的术语可能有误,但我的意思是DoSomething()在头文件中未定义(然后在源文件中定义)-很抱歉造成混淆。TestClassImpl也是从TestClass继承的吗?如果该方法在标头中定义,但在源代码中定义,则该方法不是未定义的。Matt McNabb拥有该方法。如果该方法不是虚拟的,则无法在派生自该方法的类中重写该函数(如果尝试,则函数将隐藏在非指针/非引用中)。因此,如果希望能够重写函数,请将其设置为虚拟函数。如果希望强制程序员使用代码重写函数(而不提供默认值)将其设置为纯虚拟。此处未定义哪个方法?@RakibulHasan我的术语可能有误,但我的意思是DoSomething()在头文件中未定义(然后在源文件中定义)-很抱歉造成混淆。TestClassImpl也是从TestClass继承的吗?如果该方法在标头中定义,但在源代码中定义,则该方法不是未定义的。Matt McNabb拥有该方法。如果该方法不是虚拟的,则无法在派生自该方法的类中重写该函数(如果您尝试,则函数将隐藏在非指针/非引用中)。因此,如果您希望能够重写函数,请将其设置为虚拟函数。如果您希望强制程序员使用代码重写函数(而不提供默认值),请将其设为纯虚拟函数。