クラスの静的メンバーとしてベクトルを使用して、クラス自体とその派生クラスのすべてのインスタンスを数えます。しかし、コンテナのサイズを変更しようとすると、ベクター自体からスローされたスタックオーバーフローが発生します。C++クラスインスタンスの静的コンテナとしてベクトルを使用
// initialize static values:
auto_ptr<HandleManager> ID3OBJ::HM = auto_ptr<HandleManager>(new HandleManager());
auto_ptr<vector<shared_ptr<ID3OBJ>>> ID3OBJ::ObjectList = auto_ptr<vector<shared_ptr<ID3OBJ>>>(new vector<shared_ptr<ID3OBJ>>{});
静的メンバーを上記のように空の状態で初期化します。
// constructors:
ID3OBJ::ID3OBJ(double x, double y, double z) : X(x), Y(y), Z(z), Handle(this->HM->addHandle()) { ObjectList->push_back(auto_ptr<ID3OBJ>(this));}
ID3OBJ::ID3OBJ() : X(0), Y(0), Z(0), Handle(this->HM->addHandle()) { ObjectList->push_back(shared_ptr<ID3OBJ>(this));}
Vector::Vector(double x, double y, double z) { X = x; Y = y; Z = z;
ObjectList->push_back(auto_ptr<Vector>(this));}
Vector::Vector() {
X = 0; Y = 0; Z = 0;
ObjectList->push_back(shared_ptr<Vector>(this));}
コンストラクタは、インスタンスインスタンスにObjectListという新しいインスタンスを追加します。これは意図したとおりに動作しています。
// deconstructors:
ID3OBJ::~ID3OBJ()
{
string tempH = this->Handle;
auto iter = ObjectList->end();
if (ObjectList->size() == HM->assignedHandles())
{
iter = remove_if(ObjectList->begin(), ObjectList->end(), [&](shared_ptr<ID3OBJ> ptr) {return ptr->getHandle() == tempH; });
}
ObjectList->erase(iter, ObjectList->end());
this->HM->removeHandle(this->Handle);
}
Vector::~Vector()
{
string tempH = this->Handle;
auto iter = ObjectList->end();
if (ObjectList->size() == HM->assignedHandles())
{
iter=remove_if(ObjectList->begin(), ObjectList->end(), [&](shared_ptr<ID3OBJ> ptr) {return ptr->getHandle() == tempH; });
}
ObjectList->erase(iter, ObjectList->end());
}
は、私の知る限り理解しremove_ifは、そのPREDのoccurance後の要素を持つ真を返す任意の回出てくる置き換えます。 vec [3]を引数とするpredがtrueを返す場合、vec [2]はvec [3]の代わりにvec [4]を指します。 したがって、コンテナの長さを短くするには消去機能が必要ですが、この短縮を実装するとすぐにエラーが発生します。
ヘッダーファイル:
// class-name: ID3OBJ
// Date: 30.01.2017
// Version: 1.0
// Description: The class works as base class for all used 3D-Objects, and defines the operations all 3D-Objects have, namely the Direction in case of a vector, or origion in all other cases
//
class ID3OBJ
{
public:
double X;
double Y;
double Z;
static auto_ptr<vector<shared_ptr<ID3OBJ>>> ObjectList;
ID3OBJ(double x, double y, double z);
ID3OBJ();
~ID3OBJ();
const string getHandle();
protected:
string Handle;
static auto_ptr<HandleManager> HM;
};
// class-name: I3DM
// Date: 23.03.2017
// Version: 1.0
// Description: The class works as Interface for classes which can do Vector-operations
//
template <class T> class I3DM : public virtual ID3OBJ
{
public:
using ID3OBJ::X;
using ID3OBJ::Y;
using ID3OBJ::Z;
static auto_ptr<vector<shared_ptr<T>>> ObjectList;
protected:
using ID3OBJ::Handle;
using ID3OBJ::HM;
};
// class-name: Vector
// Date: 30.01.2017
// Version: 1.0
// Description: The class works as vector, it provides an interface to acces and modify vectors, aswell as most of the vector operations
//
class Vector : public virtual I3DM<Vector>
{
public:
using I3DM<Vector>::X;
using I3DM<Vector>::Y;
using I3DM<Vector>::Z;
using I3DM<Vector>::ObjectList;
Vector(double x, double y, double z);
Vector();
~Vector();
//I'm not sure if the protected members have to be provided aswell in the header file
protected:
using ID3OBJ::Handle;
using ID3OBJ::HM;
};
HM-ヘッダ:
class HandleManager
{
public:
HandleManager();
const int assignedHandles();
const string addHandle();
void removeHandle(string hexstring);
protected:
int AssignedHandles;
forward_list<int> FreeHandles;
bool FreeHandlesAvailable;
};
CPP:
const int string_to_hex(string s)
{
int returnvalue;
stringstream stream;
stream << hex << s;
stream >> returnvalue;
return returnvalue;
}
HandleManager::HandleManager()
{
this->FreeHandlesAvailable = false;
this->AssignedHandles = 0;
}
const int HandleManager::assignedHandles()
{
return this->AssignedHandles;
}
const string HandleManager::addHandle()
{
string returnValue;
if (this->FreeHandlesAvailable)
{
returnValue = int_to_hex(this->FreeHandles.front());
this->FreeHandles.pop_front();
this->AssignedHandles++;
if (this->FreeHandles.empty()) { this->FreeHandlesAvailable = false; }
}
else
{
returnValue = int_to_hex(this->AssignedHandles);
this->AssignedHandles++;
if (this->AssignedHandles == 1) { returnValue = int_to_hex((int)0); }
}
return returnValue;
}
void HandleManager::removeHandle(string hexstring)
{
this->FreeHandlesAvailable = true;
this->FreeHandles.push_front(string_to_hex(hexstring));
this->AssignedHandles--;
}
エラーメッセージ:
未処理RVE.exeの0x00C01899の例外:0xC00000FD:スタックオーバーフロー(パラメータ:0x00000001、0x01002F48)。発生しました
パラメータ0x00000001は、ほとんどの場合ハンドルです。メモリアドレスが与えられたオブジェクトを検索する方法はありますか? (0x01002F48)
'std :: auto_ptr'の使用は決して推奨されませんでした。また、C++ 11標準から非難されており、C++ 17標準では削除されています。 –
普通のポインタを使用して、使用後にそれをクリーンアップする必要がありますが、私のエラー –
@YSとやってください。代わりに 'std :: unique_ptr'を使ってください。 – cdhowie