在堆上声明一个数组

时间:2014-09-28 04:21:20

标签: c++ arrays pointers

当我在堆上声明一个数组时,哪种方法更好?为了简单和示例,私人数据在这里公开。

我应该创建一个新指针,修改数据,然后

CAT *Family = new CAT[2];

for(int i=0; i<2;i++){
    Family[i].age = i+1;
}

VS

CAT *Family = new CAT[2];
CAT *pCat;


for(int i=0; i<2;i++){
    pCat = new CAT;
    pCat->age = i+1;
    Family[i] = *pCat;
    delete pCat;
}

4 个答案:

答案 0 :(得分:2)

直接使用原始指针和new通常不是一个好主意。

越少越好。

相反,要在堆上创建数组,请执行以下操作:

std::vector<Cat> cats( 2 );
for( int i = 0; i < int( cats.size() ); ++i ){
    cats[i].age = i+1;
}

或者,这个:

std::vector<Cat> cats;
for( int i = 0; i < 2; ++i ){
    cats.emplace_back( i+1 );
}

直接使用原始数组和new表示C程序员或无能力,因为std::vector正是为了这个目的而准确地在C ++标准库中,负责正确的内存管理。


另请注意,ALL UPPERCASE名称是用于宏的约定。我们的想法是尽量减少名称冲突和无意中文本替换的可能性。当你将这些名字用于其他事情时,你会增加名称冲突和无意中文本替换的可能性,更不用说许多程序员都将大写全部视为大喊大叫,特别强调。

答案 1 :(得分:1)

第一种方法在调用构造函数的次数方面具有明显的优势。对于你的琐碎例子,它很好。但是,假设一个类在c'tor中进行大量资源分配并将它们释放出去。 第二种方法将这些c'tors和d'tor称为额外2次,这是一个重罚。     #包括     使用namespace std;

class CAT{
public:
 CAT(){ cout<<"c'tor called"<<endl;}
 int age;
 ~CAT(){ cout<<"d'tor called"<<endl;}
};

main(){
  CAT *Family= new CAT[2];
  CAT *pCat;

  for(int i=0; i<2;i++){
    pCat = new CAT;
    pCat->age = i+1;
    Family[i] = *pCat;
    delete pCat;
  } 
}

Run it 

$./a.out 
c'tor called
c'tor called
c'tor called
d'tor called
c'tor called
d'tor called

答案 2 :(得分:0)

你的第二个实现是在堆栈上分配更多的变量,并且需要更复杂的汇编代码(我记得必须为C风格的语言生成上面代码的汇编代码,它会变得很难! )。对于奖励积分,如果您正在寻找优化,我建议您使用pre-increment in your for loop;)

答案 3 :(得分:0)

如果您尝试创建一个对象数组,我看不到第一种方法的任何优势。但是,如果您尝试创建指针数组,则可能需要第二种方法,这可能指向不同的具体类型。

struct A
{
   virtual ~A() {}
};

struct B : A
{
   int data;
}

struct C : A
{
   double data;
}


int main()
{
   A* array[20];

   // Get half of the array filled with B*.
   for (int i = 0; i < 10; ++i )
   {
      B* b = new B;
      b.data = i*10;
      array[i] = b;
   }

   // Get the other half of the array filled with C*.
   for (int i = 10; i < 20; ++i )
   {
      C* c = new C;
      c.data = i*1.5;
      array[i] = c;
   }

   // Delete the objects.
   for (int i = 0; i < 20; ++i )
   {
      delete array[i];
   }

   return 0;
}