2012-01-18 6 views
0

課題に問題があります。私はグリッドとレコードと呼ばれるクラスを持っています。レコードは、グリッド内の各位置に何回アクセスしたかを格納するグリッドです。 Gridには、Gridに変更が加えられるたびに格納できるRecordタイプのデータメンバーが含まれている必要があります。私は循環依存を避けることができましたが、スタックオーバーフローを引き起こす「循環構造」に問題があるようです。グリッドコンストラクタを呼び出すとレコードが作成され、別のレコードを作成しようとするグリッドが作成されます。私の最初の考えは、GridのRecordデータメンバをNULLに初期化するポインタにしてから、実際にコンストラクタの外でRecordオブジェクトを作成することでしたが、割り当ては特にGridのRecordデータメンバはRecord型でなければなりません。 Recordにデフォルトのコンストラクタを与えることも許可されていないので、実装が間違っていると推測しています。どのように私はこの問題を解決するための任意の提案?C++円形建設問題

Record::Record(int rows, int cols) : grid(new Grid(rows, cols)) {}; 

Grid::Grid(int rows, int cols) : record(new Record(rows, cols)) {}; 

答えて

0

私は、割り当てに誤解があるだけでなく、あまり書き込まれていないと思います。

あなたが何をしたいようだ:

Grid 
+---+---+- 
| a | b | 
+---+---+- 
| c | d | 
+---+---+- 

Record 
+---+---+- 
| 0 | 1 | 
+---+---+- 
| 2 | 2 | 
+---+---+- 

aがアクセスされていないとdは2回アクセスされましたことを示しています。

Gridに統計情報を維持するためにRecordが含まれている場合は、RecordGridにすることはできません。あなたが気づいたように、それは円形です。ただし、Recordはグリッドです。だから私はここに誤字/読書の問題があると思う。

私の提案:

class Record { 
public: 
    Record(size_t rows, size_t cols): rows(rows), cols(cols), grid(rows*cols, 0) {} 

private: 
    size_t rows; 
    size_t cols; 
    std::vector<size_t> grid; 
}; 


template <typename E> 
class Grid { 
public: 
    Grid(size_t rows, size_t cols): grid(rows*cols, 0), record(rows, cols) {} 

private: 
    std::vector<E> grid; 
    Record record; 
}; 
0

私はあなたと一緒に行くされている設計構造の種類見当がつかないが、ここではあなたの問題を解決する1つの方法です。新しいものを作成するのではなく、単に "inner"のコンストラクタに "outer"(後で説明する用語)へのポインタを渡すだけです。

だから、それは「外側」クラスは、ユーザーが使用されるべきものである

Record::Record(int rows, int cols) : grid(new Grid(rows, cols,this) {}; //outer 

Grid::Grid(Record* master) : record(master) {}; //inner 

だろう。

"インナー"クラスは、インプリメンテーション上の理由(またはイテレータや継承のようなもの)のために持っているクラスです。

上記のスタイルに従うようにコンストラクタをスワップします。ユーザーは決して行うべきではありません:Grid f(new Record(rows,cols));

これは、Javaの内部クラスのほぼ大雑把な近似です。

+0

私は残念ながら、コンストラクタの引数を変更することはできませんしています。グリッドとレコードの両方がintである2つの引数を取る必要があります。 – flurry

+1

@ SlipflurryレコードにGridへの参照が必要ですか?余計なパラメータを使わずにリファレンスを返すことは、ほとんど不可能だと思います。多分、その課題は間違って書かれたでしょう。 – Lalaland

+0

あなたは正しいかもしれません。それはもう唯一の解決策は、GridクラスからすべてをRecordにコピーして、Gridを参照しないようにすることです... – flurry

0

実際に録音してから、グリッドを単にレコードのタイプにしてから、録音機能を上書きするという仮想機能があります。次のようなものがあります。

class Record 
{ 
    virtual recordSomething(); 
} 

class Grid : Record 
{ 
    virtual recordSomething(); 
} 

私はあなたの問題を十分に理解しているかどうかはわかりませんが、これが役立つと思います。がんばろう。