0

int と文字列で構成されたクラスがありますが、そのクラス内にベクトルもあります。ファイルからレコードを読み取ってから、各行を解析した後、情報をクラスのベクトルに入れる必要があります。ID や名前などの基本的なパッケージ情報を取得し、そのパッケージで提供されるサービスを追加する必要があるため、1 つのパッケージから 10 個のレコードを取得できますが、それらはサービスの種類が異なります。今のところ、各パッケージにデータを入れて各要素からデータにアクセスしようとしていますが、クラス内のベクトルからデータを取得しようとすると、コンパイルされたファイルがクラッシュします。1233 と foo も表示されますが、テストは表示されません。それはなぜですか?

int main()
{
    vector<package> packs;
    package pack;
    pack.ID = 1233;
    pack.name = "foo";
    packs.push_back(pack);

    pack.putData("test",12);




     cout << packs[0].name << endl;
     cout << packs[0].ID << endl;
     cout << packs[0].bservice[0].serviceID << endl;    //[b]Crashes in this line[/b]

    return 0;

}

定義されたクラスは次のとおりです。

class package
{
    public:

    class aservice
    {
       public:
       int serviceID;
       string othername;
    };
    int ID;
    string name;
    vector<aservice> bservice;
    void putData(string name1, int serviceID1)
    { 
        aservice obj;
        obj.serviceID = serviceID1;
        obj.othername = name1;
        bservice.push_back(obj);
    }

};
4

4 に答える 4

5

ここでは、ベクトルに入るpackときにコピーを作成します。push_back

packs.push_back(pack);

そして、ここpackでは、ベクトルに保存されているコピーではなく、にアクセスします

pack.putData("test",12);

したがって、bserviceアクセスしようとしているベクトルは実際には空です。これが、ここでアクセスしようとするとコードがクラッシュする理由です。

cout << patients[0].bservice[0].serviceID << endl; // patients[0].bservice is empty!!!

への呼び出しの後にプッシュ バックすることで、これを回避できますputData

vector<package> packs;
package pack;
pack.ID = 1233;
pack.name = "foo";
pack.putData("test",12);
packs.push_back(pack);

ベクトルが空かどうかを最初に確認せずにベクトルにアクセスしようとしないことで、これを回避することもできます。

理想的には、デフォルトでクラスを構築し、セッターを介して段階的にデータを追加するのではなく、有用な状態に構築できるクラスを設計するよう努めるべきです。これは、データが相互に関連しており、クラスが不変条件を維持する必要がある場合に特に重要です。

于 2012-09-04T15:13:14.637 に答える
1
 packs.push_back(pack);

のコピーをpackベクターにプッシュします。したがって、2 つの特定のインスタンスがあります。そのうちの 1 つで putData を呼び出すと、もう 1 つは変更されません。そのため、書くときは

patients[0].bservice[0]

あなたのアプリケーションがクラッシュするのは、あなたが の内部ではなくputData内部patients[0]だけだったからですpack- これも別のオブジェクトです。

へのポインターを格納するようにベクトルを変更し、内部packageのアドレスをプッシュする必要があります。pack

于 2012-09-04T15:15:26.600 に答える
0
pack.push_back(pack);

pack最初が実際にであると仮定すると、これは のコピーをベクターにpacksプッシュします。pack

pack.putData("test",12);

これはローカル変数packを変更しますが、ベクトルにプッシュしたコピーは変更しません。それにはまだ空のbserviceベクトルが含まれています。

cout << patients[0].bservice[0].serviceID << endl;

patientsが実際にはであると仮定すると、これは誤って空のベクトルpacksから読み取ろうとします。bservice

putDataの前に呼び出すか、 local ではなくpacks.push_back(pack)onで呼び出します。packs.back()pack

于 2012-09-04T15:15:48.607 に答える
0

これを試して:

#include <vector>
#include <iostream>

using namespace std;

class package
{
public:
   package(int inID, const string& inName ) : ID(inID), name(inName)
   {
   }

   void putData(string name1, int serviceID1)
   { 
      aservice obj;
      obj.serviceID = serviceID1;
      obj.othername = name1;
      bservice.push_back(obj);
   }

   void Print() const
   {
      cout << ID << endl;
      cout << name << endl;

      vector<aservice>::const_iterator iter;
      iter = bservice.begin();
      for (; iter != bservice.end(); ++iter)
      {
         cout << iter->serviceID << " " << iter->othername << endl;
      }
   }

private:
   class aservice
   {
   public:
      aservice() {};
      int serviceID;
      string othername;
   };

   int ID;
   string name;
   vector<aservice> bservice;


};

typedef vector<package> PackContainer;
typedef vector<package>::iterator PackContainerIterator;
typedef vector<package>::const_iterator PackContainerConstIterator;

void PrintAll(const PackContainer& packs)
{
   PackContainerConstIterator iter = packs.begin();
   for (; iter != packs.end(); ++iter)
   {
      iter->Print();
   }
}

int main()
{
   PackContainer packs;
   package pack( 1233, "foo");
   pack.putData("test",12);
   packs.push_back(pack);
   PrintAll(packs);


   return 0;
}
于 2012-09-04T15:29:15.987 に答える