C ++: - 使用new关键字

时间:2013-06-27 07:05:27

标签: c++ pointers new-operator

我正在编写一个程序,通过使用insert-sort对办公室员工的矢量进行排序。我在插入员工记录时遇到了疑问。疑惑是: -

  1. 在评论#1中,为什么我使用指向cOffice类的指针向量?为什么我不能只使用简单对象的向量?
  2. 在评论#2中,为什么我使用new关键字在运行时创建内存?为什么我不能只复制一个类实例(以及参数),好像我正在将一个对象复制到另一个?
  3. 代码和评论如下: -

    #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
    

3 个答案:

答案 0 :(得分:2)

正如@xgbi的回答和评论中所提到的,在少数几个对象的情况下,对象的向量应该是首选。如果复制对象非常昂贵并且你有很多对象,则应该使用指针。

使用vector<cPerson>的代码无效的原因是您创建了大小为10的向量。这告诉编译器创建10个cPerson类型的对象,但没有任何参数。所以编译器试图调用cPerson();。这个构造函数不存在,你提供的唯一一个是两个字符串和一个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()

答案 1 :(得分:1)

我认为您需要指向正确建模继承的指针。 在办公室里,会有不同的人,并且建模它们的自然方式是使用基类cPerson,继承 - 例如 - cEmployee,继而由--cManager等继承。这样的建模依靠虚函数来访问常见的建模属性。

C ++需要指针(或引用)才能使用虚函数调用。因此需要指针。

答案 2 :(得分:0)

在对数组进行排序时,我认为操纵指针比操纵对象实例更快 在实例的情况下,你的InsertionSort()函数会调用大量的复制构造函数(这意味着:2个新字符串分配,2个memcpy和2个旧字符串可用内存)。在指针的情况下,它只是交换值。

所以IMO你可以使用堆实例。

现在,使用指针进行排序的好处只对几千个条目有意义。在您的情况下,有10个条目,增益并不那么重要。所以请随意切换到存储对象。这将使您的代码更小,更重要的是,更容易维护。

另外,另一个原因可能是你没有cPerson的复制构造函数,并希望保持这种方式(参见Rule of Three