問題が説明されている限り、動的に割り当てられたポリモーフィック オブジェクトのコレクションがあります。
これらのオブジェクトが特定の設計規律にどのように準拠しているかによって、ソリューションが変わる可能性があります。
- あなたはオブジェクト「葉のみのオブジェクト」ですか?(他のオブジェクト自体を参照していません)?
- 単一の非循環参照がありますか (オブジェクトはサブオブジェクトのツリーのみを形成しますか)?
- 参照間に複数のパスがありますか (2 つ以上によって参照される同じオブジェクト)
- 循環参照はありますか?
- 他のオブジェクトメンバーへの参照はありますか?
状況によっては、同じオブジェクトの複数の出力を許容できるかどうか、および最終的なループをどのように回避できるかによって、状況は非常に複雑になる可能性があります。
最初にできないことはBase
、値パラメーターとして使用することです (あなたの のように、それはコピーを作成するためです (オブジェクトがコピー可能であることを認めます: それらが他のオブジェクトを参照する場合、コピーは何をしますか? パスを乗算しますか? 参照されたオブジェクトを次のように複製します)良い?)
std::ostream&
状況 (1.) にある場合は、すべてのリーフ オブジェクトでオーバーライドされる仮想関数が必要です。operator<<(std::ostream&, Base*)
次に、オーバーロード forと別の forが必要です(std::ostream&, const std::vector<Base*>&)
このような:
class Base
{
...
public:
virtual ~Base() {} //must be polymorphic
protected:
virtual void out(std::ostream& s) =0;
friend std::ostream& operator<<(std::ostream& st, Base* pb)
{ pb->out(st); return st; }
};
class Derived1: public Base
{
...
protected:
virtual void out(std::ostream& s)
{
s << "Derived1 at " << this << " address " << std::endl;
}
};
class Derived2: public Base
{
...
protected:
virtual void out(std::ostream& s)
{
s << "Derived2 at " << this << " address " << std::endl;
}
};
std::ostream& operator<<(std::ostream& s, const std::vector<Base*>& v)
{
s << "there are " << v.size() << " objects:" << std::endl;
for(auto& i:v)
s << i;
return s;
}
あなたが状況にある場合 (2.)
class Derived3: public Base
{
...
Base* ptrOwnedobject;
};
Derived3::out
所有されている子に頼る関数を実装するだけです。
状況 (3.) にあり、同じオブジェクトを長時間印刷することを許容できない場合は、異なる親が同じ子を共有しています。子を 2 回以上保存しないように何らかの方法でマークを付け、印刷が終了したらすべての子のマークを解除する必要があります (そのメカニズムを Base クラスに設定する可能性が高くなります)。
状況 (4.) にある場合、(3.) について述べたことは、無限再帰を避けるために必須になります。
状況 (5.) にある場合は、メンバーが属しているオブジェクトも検出する必要があります (自明ではありません)。複数の継承と仮想ベースもある場合...事態はさらに複雑になります。