문제

두 객체의 바닥에 템플릿 클래스를 저장하는 데 문제가 있습니다.

는 다음과 같이 정의 된 ObjectManager라는 일반화 된 클래스를 가지고 있습니다.

template<typename T>
class ObjectManager
{}
.

와 같은 기본 클래스가 있습니다.

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

이제는 MediaSample에서 또 다른 두 개의 드라이 클래스를 선언합니다. say :

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

내 문제는 관리자 의 유형, MediaSample 클래스의 입력 매개 변수입니다.

물음표 문자 대신 유형이 아닌 유형이어야합니까?(오디오, 비디오 또는 무엇?)

더 명확한 설명을 보려면 ObjectManager의 완전한 소스를 게시했습니다. Object Manager는 미디어 샘플 개체의 폴링이며 미디어 샘플은 오디오 또는 비디오 일 수 있습니다

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;
};
.

도움이 되었습니까?

해결책

컴파일 시간 (템플릿) 및 런타임 다형성 (상속)을 혼합하기가 꽤 어려울 수 있습니다.당신이 할 수있는 일 :

a) 기본 클래스를 템플릿으로 만드십시오

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

class AudioSample : public MediaSample<AudioSample>
.

이 경우 AudioSampleVideoSample에는 공통 기본 클래스가 없으므로 원하는 것이 아닐 수도 있습니다.또는

할 수 있습니다

b) 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에 대한 포인터를 허용하고 아마도 멤버 개체에 해당 복사를 수행하는 경우 포인터를 삭제하거나 누출 할 수있는 것을 기억해야합니다.대신 값을 통과해야합니다.

다른 팁

MediaSample을 템플릿 만드는 방법 :

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

이렇게하면 파생 된 클래스 Audiosample과 VideosAmple이없는 in needs 없이는 서로 다른 종류의 MediaSample을 가질 수 있습니다.

In this case MediaSampleneeds to be a template

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

and XxxSample has to inherit from the specialized MediaSample

class AudioSample : public MediaSample<AudioSample>
{
public:
    AudioSample() : MediaSample(new ObjectManager<AudioSample>()){}
    ...
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top