ので、あなたのような何かを持っている:
class CSound {
// Whatever
};
class CSoundEngine {
// A lot of stuff
CSound* createSound(/* ... */);
};
をそして、あなたはCsoundファイルが返されたくないが、インタフェースは、それは内部でのベクトルに格納されているが、特定のタイプです?
をあなたのインターフェイスを作成し、それらから派生: - インターフェース - まあ、最初の問題
は解決するのは簡単です。
class ISound {
public:
ISound(const ISound&) = delete;
ISound(ISound&&) = delete;
ISound& operator =(const ISound&) = delete;
ISound& operator =(ISound&&) = delete;
virtual ~ISound() = default;
// Your ISound public API here as pure virtual methods, e.g.:
virtual const std::string name() const = 0;
protected:
ISound() = default;
};
class ILoopable {
public:
ILoopable(const ILoopable&) = delete;
ILoopable(ILoopable&&) = delete;
ILoopable& operator =(const ILoopable&) = delete;
ILoopable& operator =(ILoopable&&) = delete;
virtual ~ILoopable() = default;
// Your ILoopable public API here as pure virtual methods, e.g.:
virtual const bool isLoopingActive() const = 0;
virtual bool setLoopingActive(bool) = 0;
protected:
ILoopable() = default;
};
class CDefaultSound
: public ISound {
public:
CDefaultSound() = default;
// ISound implementation
inline const std::string name() const { return mName; }
private:
std::string mName;
};
class CLoopableSound
: public ISound,
public ILoopable {
public:
CLoopableSound()
: ISound(),
ILoopable(),
mLoopingActive(true),
mName("")
{
}
// ISound implementation
inline const std::string name() const { return (mName + "(Loopable)"); }
// ILoopable implementation
inline const bool isLoopingActive() const { return mLoopingActive; }
inline bool setLoopingActive(bool active) { mLoopingActive = active; }
private:
bool mLoopingActive;
std::string mName;
};
int main()
{
// Now you can do something like this, for example, using polymorphism
// in your CSoundEngine (see below)...
ISound *pDef = new CDefaultSound();
ISound *pLoopable = new CLoopableSound();
}
あなたは大丈夫ですISound由来のみCsoundファイルを使用する場合は、複数のクラスを必要としないが、その後、私はインターフェイスを使用してのポイントを理解していません。 重要:純粋な仮想インターフェイスメソッドのため、インターフェイスクラスをインストールすることはできませんので、shared_ptrやunique_ptrのようなポインタやRAIIポインタを使用する必要があります(RAIIをお勧めします...)
問題は - 特定の型をベクトルに格納することは、単一のベクタをforeachで許可する必要があるため、はるかに難しくなります。 OR!インターフェイスインスタンスを格納し、インターフェイスメソッドのみを使用します。
class DefaultSoundCreator {
static ISound* createSound(/* Criteria */) { ... }
};
template <typename TSoundCreator>
class CSoundEngine {
public:
CSoundEngine()
: mSoundCreator() {
}
std::shared_ptr<ISound> createSound(/* some criteria */);
private:
std::vector<std::shared_ptr<ISound>> mSounds;
};
// cpp
std::shared_ptr<ISound> CSoundEngine::createSound(/* some criteria */) {
// Use criteria to create specific sound classes and store them in the mSOunds vector.
ISound *pSound = TSoundCreator::createSound(/* forward criteria for creation */);
std::shared_ptr<ISound> pSoundPtr = std::shared_ptr<ISound>(pSound);
mSounds.push_back(pSoundPtr);
return pSoundPtr;
}
int main() {
std::unique_ptr<CSoundEngine<DefaultSoundCreator>> pEngine = std::make_shared<CSoundEngine<DefaultSoundCreator>>();
std::shared_ptr<ISound> pSound = pEngine->createSound(/* Criteria */);
}
あなたはISoundによって提供される機能に頼ることができる。この方法ではなく、クリエーター・クラスを指定することにより、あなたは一般的なサウンド・エンジンを搭載したサウンド作成を制御できます。
インターフェイスベースクラスを使用した実際のタイプ消去の問題:インデックス2でCLoopableSoundを保存していたが、サウンドエンジンのメソッドcreateSound()によってのみISound-Interfacemethodsを使用できることがわかった:std :: shared_ptr ;
どのようにILoopableビヘイビアにアクセスしますか?
そしてこれは、それは哲学的になる点、である...私は読書をお勧めします:私が使用したい
https://akrzemi1.wordpress.com/2013/11/18/type-erasure-part-i/ Type erasure techniques https://aherrmann.github.io/programming/2014/10/19/type-erasure-with-merged-concepts/
一つの技術:
class CLoopableSound
: public ISound {
// All the above declarations and definitions
// AND:
static std::shared_ptr<CLoopableSound> fromISound(const std::shared_ptr<ISound>& other, bool *pSuccess = nullptr) {
std::shared_ptr<CLoopableSound> p = std::static_pointer_cast<CLoopableSound>(other);
if(pSuccess)
*pSuccess = p.operator bool();
return p;
}
};
// Use like
std::shared_ptr<CLoopableSound> pLoopable = CLoopableSound::fromISound(pSoundEngine->getSound(...));
if(pLoopable) {
// Use
}
最後にもちろん、fromISound関数にテンプレートを作成し、キャストを使用してCLoopableSoundなどの代わりにILoopableにのみアクセスすることもできます。
なぜ2つの異なる言語について質問していますか?それはあなたの質問を広すぎます。あなたが最も関心のないものを削除してください。 –
私はあなたの質問の第2部分を理解していません。どうか明らかにしてください。 –
この質問はちょっと危険に似ています...あなたは抽象基本クラスがどのようなものに使われているのか尋ねていますか?コードを作成して、意味のある例で何をしようとしているのかを示している方が良いでしょう。 – luk32