Как использовать шаблонный класс в базовом классе двух разных объектов

У меня проблема с хранением шаблонов классов в базе двух объектов.

Скажем, у меня есть обобщенный класс с именем ObjectManager. Определен как:

template<typename T>
class ObjectManager
{}

И у меня есть базовый класс, как:

class MediaSample
{
public:
MediaSample(ObjectManager<?>* manager){}
private:
ObjectManager<?> mMediaSampleManager;
}

Теперь я объявляю еще два класса из MediaSample, скажем:

class AudioSample : public MediaSample
{
public:
AudioSample() : MediaSample(new ObjectManager<AudioSample>()){}
//...
}
public class VideoSample : public MediaSample
{
public:
VideoSample() : MediaSample(new ObjectManager<VideoSample>())
//...
}

Моя проблема типа менеджер, входной параметр MediaSample учебный класс.

Какой тип должен быть размещен вместо знака вопроса? (Аудио, видео или что?)

Для большей ясности я разместил полный источник ObjectManager
обратите внимание, что диспетчер объектов представляет собой опрос объектов выборки мультимедиа, а выборка мультимедиа может быть аудио или видео

class BaseMediaSampleManager
{
public:
~BaseMediaSampleManager(){}

virtual INT initialize(INT objectCount) = 0;

protected:
private:
};

template<typename T>
class MediaSamppleManager : public BaseMediaSampleMnager //(based on user2079303 advise)
{
protected:
MediaSamppleManager(void);

MediaSamppleManager(const MediaSamppleManager& manager);

MediaSamppleManager& operator = (const MediaSamppleManager& rhs);

public:

virtual ~MediaSamppleManager(void);

static MediaSamppleManager<T>* instance();

INT initialize(INT objectCount);

// take existing object from object pool and return that object
INT aquireObject(T** object);

// take back in use object to object pool
INT release(T* object);

private:
std::list<T*> mPooledSamples;
INT32 mPooledObjectCount;
INT32 mInUseObjects;
Mutex mPooledSamplesMutex;
static Mutex mSampleManagerObjectMutex;
static MediaSamppleManager<T>* mSampleManagerObject;
};

template<typename T>
Mutex MediaSamppleManager<T>::mSampleManagerObjectMutex;

template<typename T>
MediaSamppleManager<T>* MediaSamppleManager<T>::mSampleManagerObject = NULL;

template<typename T>
MediaSamppleManager<T>* MediaSamppleManager<T>::instance()
{
if (mSampleManagerObject == NULL)
{
ScopedLock<Mutex> guard(mSampleManagerObjectMutex);
if (mSampleManagerObject == NULL)
{
MediaSamppleManager<T>* temp = new MediaSamppleManager<T>();
mSampleManagerObject = temp;
}
}
return mSampleManagerObject;
}

template<typename T>
MediaSamppleManager<T>& MediaSamppleManager<T>::operator=(const MediaSamppleManager<T>& rhs)
{

}

template<typename T>
MediaSamppleManager<T>::MediaSamppleManager(const MediaSamppleManager<T>& manager)
{

}

template<typename T>
INT MediaSamppleManager<T>::release(T* object)
{
ScopedLock<Mutex> guard(mPooledSamplesMutex);
mPooledSamples.push_back(object);
mInUseObjects--;
}

template<typename T>
INT MediaSamppleManager<T>::aquireObject(T** object)
{
ScopedLock<Mutex> guard(mPooledSamplesMutex);
if (mInUseObjects == mPooledObjectCount)
{
// do we need waiting until new sample become available? or
// is it required to create new sample when no free sample exist in pool?
return 2;
}
else
{
T* temp = 0;
temp = mPooledSamples.front();
*object = temp;
mPooledSamples.pop_front();
mInUseObjects++;
}
return 1;
}

template<typename T>
INT MediaSamppleManager<T>::initialize(INT objectCount)
{
if (objectCount<=0)
{
return -1;
}
mPooledObjectCount = objectCount;
mPooledSamples.resize(objectCount);
for (int i = 0 ; i< objectCount ; i++)
{
T* temp = new T(this);
mPooledSamples.push_back(temp);
}
return 1;
}

template<typename T>
MediaSamppleManager<T>::~MediaSamppleManager(void)
{
std::cout << "MediaSampleManager Destroyed \n";
}

template<typename T>
MediaSamppleManager<T>::MediaSamppleManager(void)
:mPooledObjectCount(0)
,mInUseObjects(0)
{

}

Класс MediaSample:

class MediaSample
{
public:
// create empty media sample
MediaSample(BaseMediaSampleManager* manager);

virtual ~MediaSample(void);

virtual INT32 rate() = 0;

virtual double frameSize() = 0;

// data size of media sample
virtual INT size();

UINT* data();

ULONG samplingTime();

INT32 addRef();

INT32 release();

private:
UINT8* mMediaSampleBuffer;
// The time sample captured
ULONG mTimestamp;
// length of data
INT mDataLength;

INT mRefCount;

BaseMediaSampleManager* mMediaSampleManager;
};

Класс AudioSample:

class PMCAPI AudioSample
:public MediaSample/*<AudioSample>*/
{
public:
AudioSample(MediaSamppleManager<AudioSample>* manager);

~AudioSample();

virtual INT32 rate();

virtual double frameSize();

virtual INT size();

protected:
private:
// in 8,16 KHZ
INT32 mSampleRate;
// Mono or Stereo
INT mChannels;
// Used format ex: PCM,G729,G723,G711A,G711U
INT mCodec;
// ex : 8 bit , 16 bit
INT mBitsPerSample;
};

0

Решение

Смешать время компиляции (шаблоны) и полиморфизм времени исполнения (наследование) может быть довольно сложно. Что ты можешь сделать:

а) Сделать базовый класс шаблоном

template <class T>
class MediaSample {
ObjectManager<T> mMediaSampleManager;
};

class AudioSample : public MediaSample<AudioSample>

В этом случае AudioSample а также VideoSample не будет иметь общего базового класса, который может быть не тем, что вы хотите. Кроме того, вы можете

б) дать ObjectManager не шаблонный базовый класс (интерфейс)

class BaseManager{
virtual ~BaseManager(){}
// pure virtual functions that ObjectManager implements
};

template<typename T>
class ObjectManager: public BaseManager{
// implementation
};

class MediaSample {
BaseManager mMediaSampleManager;
// ...
};

class AudioSample: public MediaSample {
public:
AudioSample() : MediaSample(new ObjectManager<AudioSample>()){}

Кроме того, обратите внимание, что если ваш MediaSample конструктор принимает указатель на вновь созданный ObjectManager и вы предположительно скопируете это в объект-член, вы должны не забыть удалить указатель, иначе он утечет. Вы должны вероятно передать значение вместо этого.

2

Другие решения

Как насчет создания MediaSample шаблона:

template <typename T>
class MediaSample
{
public:
MediaSample(ObjectManager<T>* manager){}
private:
ObjectManager<T> mMediaSampleManager;
};

Таким образом, вы можете иметь различные виды MediaSample без необходимости иметь производные классы AudioSample и VideoSample.

0

В этом случае MediaSampleдолжен быть шаблон

template<typename T>
class MediaSample
{
public:
MediaSample(ObjectManager<T>* manager): mMediaSampleManager(manager) {}
private:
ObjectManager<T>* mMediaSampleManager;
}

а также XxxSample должен наследовать от специализированного MediaSample

class AudioSample : public MediaSample<AudioSample>
{
public:
AudioSample() : MediaSample(new ObjectManager<AudioSample>()){}
...
}
0
По вопросам рекламы [email protected]