当我在堆上声明一个数组时,哪种方法更好?为了简单和示例,私人数据在这里公开。
我应该创建一个新指针,修改数据,然后
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;
}
答案 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;
}