虚拟成员函数定义

时间:2014-02-20 17:11:34

标签: c++ oop

希望这是一个简单的问题,我不知道这实际上是什么,或者即使它是我的问题的合理解决方案。本质上我想要一个定义我想要使用的所有函数的类,但是根据我想要的那个类的'type'对这些函数有不同的定义;

baseClass.h

#include "entityclass.h"

class baseClass {
    private:
        EntityClass EntityType1; // How do I choose
        EntityClass EntityType2; // which definitions to use?
};

EntityClass.h

class EntityClass {
    private:
        int someVariables;

    public:
        EntityClass();

        virtual ~EntityClass();

        virtual void foo();
};

EntityType1.cpp

#include "EntityClass.h"

EntityClass::EntityClass()
{
    //stuff1
}

EntityClass::~EntityClass()
{
    //destructiveStuff1
}

void foo()
{
    //definition1
}

EntityType2.cpp

#include "EntityClass.h"

EntityClass::EntityClass()
{
    //stuff2
}

EntityClass::~EntityClass()
{
    //destructiveStuff2
}

void foo()
{
    //definition2
}

这是我的问题的合理解决方案,如果是这样,我如何在我的基类中指定我想用来创建我的对象的定义?我确信之前已经回答过,我只是不知道该搜索什么来找到答案。

编辑 - 哎呀,不打算包含第二个虚拟构造函数,它应该是一个析构函数!

2 个答案:

答案 0 :(得分:5)

我认为这就是你想要的:

class baseClass
{
virtual void foo() = 0; // Pure virtual function: must be implemented when 
}

class EntityClassA : baseClass
{
void foo() { ... }
}
class EntityClassB : baseClass
{
void foo() { ... }
}

现在,您可以在调用时定义所需的类:

baseClass *myObj = new EntityClassA();
myObj->foo(); // Calls foo() in EntityClassA
myObj = new EntityClassB();
myObj->foo(); // Calls foo() in EntityClassB

注意,如果你有析构函数,它也应该声明为virtual,这样当删除baseClass时,它也会调用子类的析构函数。

答案 1 :(得分:1)

首先,您无法定义虚拟构造函数,即virtual EntityClass()

原因很简单:每个实例都包含一个指向其类的虚函数表的指针。调用构造函数时,此指针仅指定 (基于实例的显式类型)。

虚函数背后的重点是,您不需要指定“调用”它们的实例的确切类型。相反,此类型在运行时(使用对象指向V表的指针)“确定” 创建实例后。因此,实例本身(即构造函数)的创建不能通过虚函数机制完成。

相比之下,基类的析构函数应通常声明为virtual,以确保在实例为时调用任何子类实例的析构函数“封端”。

关于你的问题,你需要做的只是继承两个不同的类来自基类。

这是一种简单的方法:

class baseClass
{
protected:
    baseClass();          // implement it in the source file
    virtual ~baseClass(); // implement it in the source file
    virtual void foo()=0; // or implement it in the source file if it has any meaning in the base class
};

class EntityClass1 : public baseClass
{
public:
    EntityClass1();  // implement it in the source file
    ~EntityClass1(); // implement it in the source file
    void foo();      // implement it in the source file
};

class EntityClass2 : public baseClass
{
public:
    EntityClass2();  // implement it in the source file
    ~EntityClass2(); // implement it in the source file
    void foo();      // implement it in the source file
};