2 つの動的コンテナーに対して「+」演算子をオーバーロードする必要があります。
Occurance Occurance::operator +(const Occurance& occ) const {
Occurance* result = new Occurance;
Iterator i1(head);
Iterator i2(occ.head);
while( !(i1.isNULL() && i2.isNULL()) ) {
if(i1.getCount() >= i2.getCount()) {
result->add(i1.getFile());
result->tail->count = i1.getCount();
++i1;
}
else {
result->add(i2.getFile());
result->tail->count = i2.getCount();
++i2;
}
}
return *result;
}
私がする時:
Occurance occ = occ1+occ2;
リストの先頭へのポインタは正しくコピーされ、すべて正常に動作しますが、結果への参照が失われています。occ デストラクタが呼び出されると、リスト全体が破棄されますが、結果の最初の要素は参照ではなくコンテンツをコピーしただけなので、破棄されません。
戻り値の型を参照に変更すると、同じことが発生しますが、割り当て中に発生します。
別のアイデアは、「結果」を動的に作成しないことです。そのため、関数の最後で自動的に破棄されますが、リスト全体を破棄するデストラクタを呼び出しています。
このような構造を作成し、このメモリリークなしで返す簡単で「適切な」方法はありますか? もちろん、「+」演算子から期待されるように、返される型はオブジェクトまたは参照でなければなりません。
デストラクタで関数へのポインタを変更することを含む厄介なハックを見つけましたが、非常に単純なものが欠けているだけでしょうか?
編集: もちろん、クラスは 3 のルールに従います。割り当ては次のとおりです。
Occurance& Occurance::operator =(const Occurance& occ) {
destruct();
head = occ.head;
current = occ.current;
tail = occ.tail;
return *this;
}
Occurance::Occurance(const Occurance& occ) {
head = occ.head;
current = occ.current;
tail = occ.tail;
}
Occurance::~Occurance() {
destruct();
}
destruct は、'head' で始まるリストを破棄するだけです。
クラス宣言:
class Occurance {
private:
class Node {
public:
Node* next;
Node* prev;
int count;
const File* file;
Node(const File& a_file, Node* a_prev);
};
Node* head;
Node* tail;
Node* current;
void destruct();
public:
class Iterator {
private:
Node* node;
public:
Iterator();
Iterator(Node* a_node);
void operator ++();
const File& getFile();
int getCount();
bool isNULL();
};
Occurance();
Occurance(const Occurance& occ);
void add(const File& a_file);
Occurance& operator =(const Occurance& occ);
Occurance operator +(const Occurance& occ) const; //dodaje listy zachowując sortowanie
Iterator begin() const;
virtual ~Occurance();
};