Определения виртуальных функций-членов

0

Надеюсь, простой вопрос, я не знаю, что это на самом деле называется, или даже если это разумное решение моей проблемы. По сути, я хочу иметь класс, который определяет все функции, которые я хочу использовать, но имею разные определения этих функций в зависимости от того, что "тип" этого класса я хочу;

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, не намеревался включить второй виртуальный конструктор, он должен был быть деструктором!

  • 0
    Я не уверен, что предложенное вами решение является разумным. Можете ли вы рассказать нам больше о том, что вы пытаетесь смоделировать?
  • 1
    похоже, это может помочь - tutorialspoint.com/cplusplus/cpp_interfaces.htm
Показать ещё 2 комментария
Теги:
oop

2 ответа

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 он также baseClass деструкторы для подклассов.

  • 1
    Не должен ли myObj указателем? baseClass * myObj = new EntityClassA ();
  • 0
    Он прав, вы должны исправить свой пост.
Показать ещё 2 комментария
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
};
  • 0
    Извините, опечатка, это был виртуальный деструктор!
  • 0
    Итак, я предполагаю, что полное описание механизма виртуальной функции в этом случае немного избыточно (если только оно не дает вам лучшего восприятия в целом). В любом случае, остальная часть ответа по-прежнему актуальна для вашего вопроса.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню