私はヒープ上に作成されたオブジェクトへのポインタを保持し、ハウスキーピングを担当するObjectクラスとObjectManagerクラスを持っています。すなわち、(例えば、オブジェクトが値によって関数に渡されたときなどのように、一時オブジェクトへのポインタを持ちたくない)。私は、ObjectManagerクラスの項目についていくつかの処理を行い、後でメモリを解放したいと思います。ヒープ上にのみ作成されたクラスのオブジェクトを管理および処理する方法は?
次のファイルをご検討ください:
"Object.h" ファイル
#pragma once
#include<algorithm>
#include "ObjectManager.h"
class ObjectManager;
class Object{
private:
int value;
static bool heap_flag;
public:
Object() {
if (heap_flag) {
heap_flag = false;
ObjectManager::vo.push_back(this);
}
}
~Object() {}
void* operator new (size_t sz){
heap_flag = true;
return malloc(sz);
}
void setValue(int v) { value = v; }
};
と "ObjectManager.h" クライアントコードで、最終的
#pragma once
#include "Object.h"
#include <vector>
using namespace std;
class Object;
class ObjectManager{
private:
ObjectManager() {}
public:
static vector <Object*> vo; // vector that holds pointers to all objects created on heap
static void releaseObjects() {
size_t index = 0;
for (auto o : vo){
// iterate through the vector and delete the object create on heap
delete o;
vo[index] = NULL;
index++;
}
}
};
:
#include <iostream>
#include "Object.h"
#include "ObjectManager.h"
using namespace std;
bool Object::heap_flag = false;
vector<Object*> ObjectManager::vo;
void process_Heap_objects (vector<Object*>) {
// ... code to iterate through the elements of a vector and do some process
}
int main() {
Object o; // created on stack
Object* po = new Object(); // created on heap
ObjectManager::vo[0]->setValue(100);
process_Heap_Objects(ObjectManager::vo);
ObjectManager::releaseObjects();
return 0;
}
whこのファイルをコンパイルすると、VS2013で次の警告が表示されます。 - > "警告C4150:不完全な型 'Object'へのポインタの削除。呼び出されていないデストラクタ 1> Objectmanager.h:。
の1-警告が何を意味する:
コードは罰金コンパイルしてかの期待どおりに動作
二つの質問「オブジェクト」」の宣言を参照してください?
2 - これはあなたの考えは何ですか?これを達成するためのより良い方法はありますか?良いデザインです?
あなたはObject' 'は' virtual'デストラクタを持つようにしたい:使用することをお勧めしますほとんどのスタイルガイドには警備員が含まれていることをせず、あなたが 'へのポインタをdelete'ing未定義の動作を取得します派生型のオブジェクト。また、 'operator new()'を定義するときに、一致する 'operator delete()'を指定する必要があることに注意してください。 –
良い点、私はこのクラスから派生するつもりはありません。 – Arash
コンパイラにはObjectの前方宣言のみがあり、デストラクタがあるかどうかはわかりません。 releaseObjects()の前に定義する必要があります。 –