私は、STLを使用せずにスポーツ組織用にc ++でデータベースを作成する必要がある割り当てを行っています(独自のリストと文字列を作成しました)。データベースは、データを二重にリンクされたリストに保持しています。ノードのほかに、チームであるデータがあります。もちろん、チームの種類は1つだけではなく、現在3つあります。これらのオブジェクトは、チームオブジェクトを継承しました。テキストファイルを読んでオブジェクトを作成することを除いて、すべてが機能するようにしました。
私はすでに、プログラムが読み取る最初の情報であるマーカーを作成しようとしました。マーカーは、3つのクラスのどれを作成する必要があるかを決定し、他のデータを読み取って、新しいオブジェクトを作成し、それを配置します。二重リンクリストの最後にあります。残念ながら、それは機能せず、代わりに何もせず、何も起こらなかったようにプログラム全体を続行します。
void hozzaad(ListaElem *s, team *data) { ///adding to the end
ListaElem *iter = s;
while (iter->kov=NULL)
{
iter = iter->kov;
}
ListaElem *uj = new ListaElem(data);
uj->elozo = iter;
iter->kov = uj;
}
void listaz(ListaElem *s) { //print out all that is in the list
if (s == NULL) {
std::cout << "Ures lista" << std::endl;
return;
}
ListaElem *iter = s;
while (iter!=NULL)
{
iter->adat->kiirt(std::cout);
iter = iter->kov;
}
}
void listament(ListaElem *s, const char *a) { //this one creates the file
std::ofstream file;
file.open(a);
ListaElem *iter = s;
if (file.is_open()) {
while (iter != NULL) {
file << iter->adat->Getclub()<< "\n";
file << iter->adat->Getname() << "\n" << iter->adat->Getmember()<< "\n";
if (iter->adat->Getclub() == 1) {
file << iter->adat->Getsupport() << "\n";
}
if (iter->adat->Getclub() == 2) {
file << iter->adat->Getpompom() << "\n";
}
if (iter->adat->Getclub() == 3) {
file << iter->adat->Getname1() << "\n" << iter->adat->Getname2() << "\n";
}
iter = iter->kov;
}
}
else
{
std::cout << "Nem tudom kinyitni a file-t";
}
file.close();
return;
};
void test4() { // the basic test
Handball c("Kezes HC", 21, 50000);
team adat("", 0);
ListaElem *egyik = new ListaElem(&adat);
hozzaad(egyik,&c);
ListaElem *uj = new ListaElem(&adat);
listament(egyik, "test.txt");
std::ifstream file;
file.open("test.txt");
if (!(file.is_open())) {
std::cout << "hiba\n";
return;
}
int micsoda;
while (file >> micsoda);
{
if (micsoda == 1) {
String beolvas("");
int m;
int d;
getline(file, beolvas);
file >> m;
file >> d;
Handball ujh(beolvas, m, d);
hozzaad(uj, &ujh);
beolvas = "";
}
if (micsoda == 2) {
String fbeolvas("");
int fm;
String e1("");
String e2("");
getline(file, fbeolvas);
file >> fm;
getline(file, e1);
getline(file, e2);
football ujh(fbeolvas, fm, e1, e2);
hozzaad(uj, &ujh);
}
if (micsoda == 3) {
String bbeolvas("");
int bm;
int bd;
getline(file, bbeolvas);
file >> bm;
file >> bd;
Basketball ujh(bbeolvas, bm, bd);
hozzaad(uj, &ujh);
}
}
std::cout << "OK" << std::endl;
listaz(uj);
file.close();
std::cout << "OK" << std::endl;
}
test4() expects to go out like:
OK Kezes HC 21 50000 OK
コードを絶対に必要なものに短縮する:
if (micsoda == 1)
{
Handball ujh;
hozzaad(uj, &ujh);
} // at this point in code, your object ujh runs out of scope!!!
オブジェクトがスコープを使い果たすと、オブジェクトは破棄され(クラスのデストラクタに出力ステートメントを追加するとわかります...)、オブジェクトへのポインタは無効になります。特に、リスト内のものは無効になります(ダングリングポインター、または同じことが起こり得る参照について話します)。現在、それらを使用すると、未定義の動作が発生します。つまり、何かが発生する可能性があります。運が悪ければ(または、見方によっては運が良ければ)、プログラムがクラッシュすることさえあります。
コードの重要な部分が不足しているため、クラス内のオブジェクトへのポインタのみを格納すると想定していることに注意してくださいListaElem
。ただし、格納されるクラスはポリモーフィックであるため、これはかなり可能性が高いです...
ただし、必要なのは、プログラムがifブロックにある間よりも長く存続するオブジェクトです。実際のシナリオをターゲットにしていると仮定すると、同じタイプの複数のオブジェクトが必要になる可能性があるため、オブジェクトをif句から移動するだけではオプションはありません。したがって、オブジェクトを動的に作成します。ただし、メモリ管理と所有権の質問にも対処する必要があります。メモリ管理部分を処理するのが最も簡単なのは、スマートポインタを使用することです。所有?リストがオブジェクトの唯一の所有者であると想定するのは合理的であるように思われるので、次のようにすることができます。
class ListElem
{
std::unique_ptr<Team> m_data;
public:
ListElem(std::unique_ptr<Team> data) // accepting a unique_ptr already here indicates
// clearly that the item will grab ownership
: m_data(std::move(data)) // unique_ptr is only movable, not copiable!
{ }
}
次に、上記のコードを次のように変更できます。
if (micsoda == 1)
{
int n, m; // sample data
hozzaad(uj, std::make_unique<Team>(n, m); // arguments are passed directly to
// the constructor of class Team
}
OK、STLの使用は許可されていません。次に、スマートポインターmake_unique
と、move
テンプレート関数を自分で作成します(リストと文字列の場合と同じように)。cppreferenceで、サンプルの実装を見つけることができますstd::make_unique
。コードをコピーして貼り付けるだけでなく、最初に理解し、自分で最初から書き直すのが最善です。そうしないと、何も学習できません(上記の私のコードにも同じことが当てはまります)。または、教師にスマートポインタのSTLで例外を設けるかどうかを尋ねるかもしれません。
最後のアドバイス:一般に、連続したメモリでの操作は、システムRAM全体に分散している可能性のあるメモリでの操作よりもはるかに高速です。したがって、のstd::vector
代わりに再実装することを検討してくださいstd::list
。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加