Надеюсь, простой вопрос, я не знаю, что это на самом деле называется, или даже если это разумное решение моей проблемы. По сути, я хочу иметь класс, который определяет все функции, которые я хочу использовать, но имею разные определения этих функций в зависимости от того, что "тип" этого класса я хочу;
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
}
Является ли это разумным решением моей проблемы, и если да, то как я могу указать в своем базовом классе, какие определения я хочу использовать для создания моего объекта? Я уверен, что на это уже был дан ответ, я просто не знаю, что искать, чтобы найти ответ.
EDIT - oops, не намеревался включить второй виртуальный конструктор, он должен был быть деструктором!
Я думаю, это то, что вы хотите:
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
он также baseClass
деструкторы для подклассов.
Во-первых, вы не можете определить виртуальный конструктор, т. 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
};