создание объекта производного класса с существующим объектом базового класса? - PullRequest
3 голосов
/ 23 марта 2011

Существует ли возможность (или быстрый обходной путь) создания объекта, определенного как производный класс, без создания объекта базового класса в памяти; вместо этого производный объект должен ссылаться на реально существующий объект базового класса («захват» его резидентной памяти)? Это необходимо по соображениям скорости: создание нового производного объекта, копирование в него данных из объекта базового класса, а затем уничтожение базового объекта занимает слишком много времени.

Ответы [ 6 ]

2 голосов
/ 23 марта 2011

В этом случае вы можете рассмотреть состав вместо наследования - это будет более естественным.

1 голос
/ 23 марта 2011

Я бы не использовал конструкцию class, поддерживаемую языком.Если вам нужно что-то маленькое и гибкое, подумайте о написании struct и реализации своих собственных v-table с использованием указателей на функции.Примерно так же, как это делается, например, в ядре Linux.Обратите внимание, что объектно-ориентированное программирование может быть выполнено практически на любом языке, не обязательно на том, который его поддерживает.

Затем вы можете переключить указатель v-таблицы на лету и, возможно, выполнить некоторое realloc, чтобы добавитьполя, обязательные для производного типа.

В конце концов вы можете упаковать все это в обычный class, который не имеет динамических методов и просто делегирует все вызовы описанной внутренней структуре.Это не должно налагать никакой памяти или вычислительных затрат.

РЕДАКТИРОВАТЬ: На самом деле я думаю, realloc это не путь.Это процедура, которая задействует основную операционную систему и требует переключения контекста.Почти всегда вызов copy будет быстрее, если у вас уже выделен соответствующий блок памяти.Если вы заинтересованы в скорости, то, возможно, рассмотрите возможность реализации собственного управления памятью или использования одной из альтернативных реализаций, предоставляемых библиотеками, таких как boost.

0 голосов
/ 13 июля 2016

Рассматривали ли вы шаблон фабричного дизайна?

Ваш базовый класс должен знать только, какой класс вы хотите создать

0 голосов
/ 19 июля 2013

Если вы хотите создать одну версию базового класса и все объекты наследуются или наследуются от одного и того же экземпляра, то вы можете объявить вещи как статические в базовом классе.Статический означает одну его версию для каждого экземпляра класса.

т.е.

class FooBase {
protected:
    static int IDCnt;
    static int ObjCnt;
    int ID;
public:
    FooBase();
    ~FooBase();
    virtual int GetID();
    virtual int GetObjCnt();
    virtual int GetIDCnt();
};
//implementation
int FooBase::IDCnt = 0; //need to init static vars
int FooBase::ObjCnt = 0;
FooBase::FooBase() { ID = IDCnt; IDCnt++; ObjCnt++; }
FooBase::~FooBase() { ObjCnt--; }
int FooBase::GetID() { return ID; }
int FooBase::GetObjCnt() { return ObjCnt; }
int FooBase::GetIDCnt() { return IDCnt; }

#include "FooBase.h"
class FooDerived : public FooBase {
      //blah

};
#include "FooDervied.h"

int main() {
FooDerived A;
FooDerived B;
cout << A.GetID() << ' ' << A.GetObjCnt() << ' ' << A.GetIDCnt() << endl;
cout << B.GetID() << ' ' << B.GetObjCnt() << ' ' << B.GetIDCnt() << endl;
if(true) {
   FooDerived C;
   cout << A.GetObjCnt() << ' ' << A.GetIDCnt() << ' ' << B.GetObjCnt << C.GetIDCnt() << endl;
}
cout << B.GetObjCnt() << '' << A.GetObjCnt() << ' ' << A.GetIDCnt() << ' ' << B.GetIDCnt << endl;

}

Таким образом, вы не объявляете элемент базового класса, вместо этого экземпляр базового классанаследуется через статические переменные, что в основном означает, что все FooDerived просматривают один и тот же блок памяти для FooBase::IDCnt и FooBase::ObjCnt.

0 голосов
/ 23 марта 2011

Если вам нужен класс, производный от динамического вызова, v-таблица обязательна.

Так что, возможно, вы можете реализовать «базовый класс» без элемента данных и передать данные или указатель данных, которые ваш виртуальныйфункции должны быть аргументом во время вызова.

Это сэкономит память, но будет стоить больше времени.

0 голосов
/ 23 марта 2011

Я не думаю, что вы можете делать то, что, кажется, хотите.

Рассмотрим:

   d1 = prestochango(b);
   d2 = prestochango(b);
   d1.blarf = waldo;
   // what value does d2.blarf now have?

Либо d1 и d2 являются разными объектами, включая разные b-субстраты, либо это один и тот же объект.

Теперь вы МОЖЕТЕ подделать его, сделав ваш b-субстрат статическим членом вашего класса d.

...