2

複合デザインパターンを理解するために、以下のプログラムを実装しました。私はC++11のいくつかの概念も使用しました。しかし、私の悪いことに、このプログラムは実行中にセグメンテーション違反を引き起こしています。GDBでデバッグしようとしたところ、getID()関数に問題があることがわかりました。

#0  0x08049a12 in Employee::getID (this=0x0) at Composite.cpp:27
27      int getID(){return ID;}

しかし、それでも私はその機能の何が問題になっているのか理解できませんか?誰かが助けることができるかどうか感謝します。

#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

class Employee
{
    protected:
    int ID;
    string Name;
    string Role;

    public:
    Employee(int empID, string empName, string empRole)
    {
        ID=empID;
        Name=empName;
        Role=empRole;
    }
    virtual void showDetails()=0;
    virtual void addWorker(shared_ptr<Employee> newWorker)=0;
    virtual void deleteWorker(shared_ptr<Employee> employee)=0;
    virtual ~Employee(){}
    int getID(){return ID;}
};

class Worker : public Employee
{
    public:
    Worker(int empID, string empName, string empRole)
        : Employee(empID, empName, empRole) {}

    void showDetails()
    {
        cout<<Name<<" ("<<ID<<") "<<Role<<endl;
    }

    void addWorker(shared_ptr<Employee> newWorker){};
    void deleteWorker(shared_ptr<Employee> employee){};
};

class Supervisor : public Employee
{
    private:
    vector<shared_ptr<Employee>> myTeam;

    public:
    Supervisor(int empID, string empName, string empRole)
        : Employee(empID, empName, empRole) {}

    void addWorker(shared_ptr<Employee> newWorker)
    {
        myTeam.push_back(newWorker);
    }

    void deleteWorker(shared_ptr<Employee> employee)
    {
        int pos=0;
        for (auto temp : myTeam)
        {
        if (temp->getID()!=employee->getID())
            ++pos;
        else
            myTeam.erase(myTeam.begin()+pos);
        }
    }

    void showDetails()
    {
        cout<<Name<<" ("<<ID<<") "<<Role<<" ---->"<<endl;
        for (auto worker : myTeam)
        {
        worker->showDetails();
        }
        cout<<endl;
    }
};

int main()
{
    shared_ptr<Employee> Tushar(new Worker(376653,"Tushar Shah","Team mate"));
    shared_ptr<Employee> Ranjeet(new Worker(469725,"Ranjeet Aglawe","Team mate"));
    shared_ptr<Employee> Kiran(new Supervisor(137581,"Kiran Asher","Manager"));
    shared_ptr<Employee> Namita(new Supervisor(122110,"Namita Gawde","Manager"));
    shared_ptr<Employee> Rumman(new Supervisor(122022,"Rumman Sayed","Manager"));
    shared_ptr<Employee> Rajendra(new Supervisor(111109,"Rajendra Redkar","Manager"));
    shared_ptr<Employee> Sameer(new Supervisor(106213,"Sameer Rajadhyax","Group Lead"));

    Kiran->addWorker(Tushar);
    Kiran->addWorker(Ranjeet);
    Sameer->addWorker(Kiran);
    Sameer->addWorker(Namita);
    Sameer->addWorker(Rumman);
    Sameer->addWorker(Rajendra);

    Sameer->showDetails();

    Sameer->deleteWorker(Rumman);
    Sameer->showDetails();

    return 0;
}
4

3 に答える 3

3

変化する

else
    myTeam.erase(myTeam.begin()+pos);

else {
    myTeam.erase(myTeam.begin()+pos);
    break;
}

クラッシュを修正するには(ideoneのデモ;なしbreakで、SIGSEGVでクラッシュします)。問題は、その要素の1つを消去した後でも、ベクトルの反復を継続することです。これは許可されていません。

削除するワーカーは1つだけなので(一意であると想定ID)、要素が消去された後に続行することは、とにかく良い考えではありませんでした。

于 2013-02-10T12:12:08.890 に答える
3

あなたの問題は、C ++とSTLの非常に一般的な落とし穴です。つまり、反復中に注意を払わずに消去しているのです。ここ:

    for (auto temp : myTeam)
    {
    if (temp->getID()!=employee->getID())
        ++pos;
    else
        myTeam.erase(myTeam.begin()+pos);
    }

一般に、STLコンテナを反復処理しながら消去することはできません。代わりに、後で削除する要素を「マーク」するか、整数ベースまたはイテレータベースの反復を使用して、より正確に制御できるようにすることを検討してください。とにかくこの「pos」変数があるので、ここではおそらく単純な整数ベースのforループを使用します。

于 2013-02-10T12:12:48.397 に答える
0

問題はおそらくdeleteWorkerメソッドにあります。コンテナを変更しながら、コンテナを反復処理しています。

私は2つの可能な解決策のうちの1つを提案します

  • 削除するアイテムのインデックスを見つけて、昇順でベクターに保存します。次に、ベクトルを降順で繰り返し、それらを削除します。
  • std::remove_ifをvector::eraseと組み合わせて使用​​します。ここで例を見ることができます
于 2013-02-10T12:13:17.680 に答える