0

挿入ソートを使用してオフィス従業員のベクトルをソートするプログラムを作成しています。従業員の記録を挿入している間、私は疑問に直面しています。疑問は次のとおりです。

  1. コメント #1 で、なぜ cOffice クラスへのポインタのベクトルを使用しているのですか? 単純なオブジェクトのベクトルを使用できないのはなぜですか?
  2. コメント #2 で、newキーワードを使用して実行時にメモリを作成するのはなぜですか? オブジェクトを other にコピーしているかのように、(引数とともに) クラス インスタンスをコピーできないのはなぜですか?

コメント付きのコードは次のとおりです。

#include<iostream>
#include<vector>
#include<string>
using namespace std;
class cPerson
{
    private:
    string firstname,lastname;
    int age;
    public:
    cPerson(string fn,string ln,int a)      // constructor to input the firstname, lastname and age of the person
    {
        firstname=fn;
        lastname=ln;
        age=a;
    }
    void displaycPerson()
    {
        cout<<"First Name = "<<firstname<<"\n";
        cout<<"Last Name = "<<lastname<<"\n";
        cout<<"Age = "<<age<<"\n";
    }
    string getLastName()
    {
        return lastname;
    }
};
class cOffice
{
    private:
        vector<cPerson*> v;         // Comment#1 and the alteranate code is: vector<cPerson> v;
        int nElem;                      
    public:
        cOffice(int max)
        {
            v.resize(max);              
            nElem=0;                    
        }
        ~cOffice()
        {
            for(int i=0;i<nElem;i++)    // no use of the destructor if the above code is implemented
                delete v[i];
        }
        void insertRec(string fn1, string ln1, int a1)      // inserting the record
        {
            v[nElem] = new cPerson(fn1,ln1,a1);     // Comment#2 and the alteranate code is: v[nElem] = cPerson(fn1,ln1,a1);
            nElem++;
        }
        void InsertionSort()
        {
            int compare,pivot;
            for(pivot=1;pivot<nElem;pivot++)
            {
                cPerson* temp = v[pivot];       
                compare=pivot;
                while(compare>0&&v[compare-1]->getLastName()>=temp->getLastName())
                {   
                    v[compare]=v[compare-1];
                    compare--;
                }
                v[compare] = temp;
            }
        }   
        void display()
        {
            for(int i=0;i<nElem;i++)
                v[i]->displaycPerson();
        }
};
int main(void)
{
    cOffice obj(10);
    obj.insertRec("Evans", "Patty", 24); 
    obj.insertRec("Adams", "Henry", 63);
    obj.insertRec("Yee", "Tom", 43);
    obj.insertRec("Smith", "Lorraine", 37);
    obj.insertRec("Hashimoto", "Sato", 21);             
    obj.insertRec("Stimson", "Henry", 29);
    obj.insertRec("Velasquez", "Jose", 72);
    obj.insertRec("Lamarque", "Henry", 54);
    obj.insertRec("Vang", "Minh", 22);
    obj.insertRec("Creswell", "Lucinda", 18);
    obj.display();
    obj.InsertionSort();
    obj.display();
    return 0;
}

明らかに、コードの残りの部分は、すべての逆参照演算子を置き換え->て削除することにより、それに応じて変更されます。.*

質問で言及したすべての編集を行うと、プログラムは次のようなエラーを表示します。

In member function 'void std::vector<_Tp, _Alloc>::resize(std::vector<_Tp, Alloc>::size_type, std::vector<_Tp, _Alloc>::value_type) [with _Tp = cPerson; _Alloc = std::allocator<cPerson>; std::vector<_Tp, _Alloc>::size_type = unsigned int; std::vector<_Tp, _Alloc>::value_type = cPerson]':
   exp.cpp:40:16: error: no matching function for call to 'cPerson::cPerson()'
   exp.cpp:40:16: note: candidates are:
   exp.cpp:11:2: note: cPerson::cPerson(std::string, std::string, int)
   exp.cpp:11:2: note:   candidate expects 3 arguments, 0 provided
   exp.cpp:5:7: note: cPerson::cPerson(const cPerson&)
   exp.cpp:5:7: note:   candidate expects 1 argument, 0 provided
4

3 に答える 3

2

回答とコメントで述べたように@xgbi、オブジェクトの数が少ない場合は、オブジェクトのベクトルを優先する必要があります。オブジェクトのコピーが非常に高価であり、オブジェクトがたくさんある場合は、ポインターを使用する必要があります。

vector<cPerson>を使用したコードが機能しない理由は、サイズが 10 のベクトルを作成するためです。これは、型 のオブジェクトを 10 個作成するようコンパイラに指示しますcPersonが、引数はありません。そのため、コンパイラは を呼び出そうとしますcPerson();。このコンストラクターは存在しません。提供するのは、2 つの文字列と int を持つものだけです。

この方法でコードを変更します

cOffice(int max)
{
    v.reserve(max); // not strictly necessary, but may improve performance      
}

void insertRec(string fn1, string ln1, int a1)
{
    v.push_back(cPerson(fn1,ln1,a1));
}

代わりにnElemを使用する必要がありますv.size()

于 2013-06-27T07:35:10.093 に答える
0

配列をソートするときは、オブジェクトのインスタンスを操作するよりもポインターを操作する方が速いと思います。
インスタンスInsertionSort()の場合、関数は大量のコピー コンストラクターを呼び出します (つまり、2 つの新しい文字列の割り当て、2 つの memcpy、古い文字列での 2 つのメモリの解放)。ポインターの場合は、値を交換するだけです。

したがって、ヒープインスタンスを使用しても問題ありません。

現在、ソートにポインターを使用する利点は、数千のエントリに対してのみ重要です。あなたの場合、10 エントリで、ゲインはそれほど重要ではありません。そのため、代わりにオブジェクトの保存に自由に切り替えてください。これにより、コードが小さくなり、さらに重要なことに、保守が容易になります。

また、別の理由として、cPerson のコピー コンストラクターがなく、それを維持したいことが考えられます ( 3 つのルールを参照) 。

于 2013-06-27T07:09:29.397 に答える