对象数组初始化没有默认的构造函数

#include <iostream> class Car { private: Car(){}; int _no; public: Car(int no) { _no=no; } void printNo() { std::cout<<_no<<std::endl; } }; void printCarNumbers(Car *cars, int length) { for(int i = 0; i<length;i++) std::cout<<cars[i].printNo(); } int main() { int userInput = 10; Car *mycars = new Car[userInput]; for(int i =0;i < userInput;i++) mycars[i]=new Car[i+1]; printCarNumbers(mycars,userInput); return 0; } 

我想创build一个汽车数组,但我得到以下错误:

 cartest.cpp: In function 'int main()': cartest.cpp:5: error: 'Car::Car()' is private cartest.cpp:21: error: within this context 

是否有一种方法来使这个初始化没有使Car()构造函数公开?

不。

但是! 如果您使用std::vector<Car> ,就像您应该(永远不会使用new[] )一样,那么您可以指定应该如何构造元素*。

*很好。 您可以指定要复制的值。


喜欢这个:

 #include <iostream> #include <vector> class Car { private: Car(); // if you don't use it, you can just declare it to make it private int _no; public: Car(int no) : _no(no) { // use an initialization list to initialize members, // not the constructor body to assign them } void printNo() { // use whitespace, itmakesthingseasiertoread std::cout << _no << std::endl; } }; int main() { int userInput = 10; // first method: userInput copies of Car(5) std::vector<Car> mycars(userInput, Car(5)); // second method: std::vector<Car> mycars; // empty mycars.reserve(userInput); // optional: reserve the memory upfront for (int i = 0; i < userInput; ++i) mycars.push_back(Car(i)); // ith element is a copy of this // return 0 is implicit on main's with no return statement, // useful for snippets and short code samples } 

附加function:

 void printCarNumbers(Car *cars, int length) { for(int i = 0; i < length; i++) // whitespace! :) std::cout << cars[i].printNo(); } int main() { // ... printCarNumbers(&mycars[0], mycars.size()); } 

注意printCarNumbers实际上应该devise得不同,接受两个表示范围的迭代器。

您可以像这样使用展示位置:

 class Car { int _no; public: Car( int no ) :_no( no ) { } }; int main() { void* raw_memory = operator new[]( NUM_CARS * sizeof( Car ) ); Car* ptr = static_cast<Car*>( raw_memory ); for( int i = 0; i < NUM_CARS; ++i ) { new( &ptr[i] )Car( i ); } // destruct in inverse order for( int i = NUM_CARS - 1; i >= 0; --i ) { ptr[i].~Car(); } operator delete[]( raw_memory ); return 0; } 

更有效的C ++参考 – Scott Meyers:
项目4 – 避免无偿的默认构造函数

您可以创build一个指针数组。

 Car** mycars = new Car*[userInput]; for (int i=0; i<userInput; i++){ mycars[i] = new Car(...); } ... for (int i=0; i<userInput; i++){ delete mycars[i]; } delete [] mycars; 

要么

Car()构造函数不需要公开。 将静态方法添加到构build数组的类中:

 static Car* makeArray(int length){ return new Car[length]; } 

不,没有。 新expression式只允许默认初始化或根本不初始化。

解决方法是使用operator new[]分配原始内存缓冲区,然后使用带有非默认构造函数的placement-new构造该缓冲区中的对象。

好问题。 我有同样的问题,并在这里find。 真正的答案是,@ Dan-Paradox,没有标准的语法方法。 所以,所有这些答案都是解决问题的多种select。

我自己读了答案,并没有特别发现任何一个完美的个人习惯。 我可能坚持的方法是使用默认的构造函数和set方法:

类MyClass
 {
   int x,y,z;
上市:
   MyClass():x(0),y(0),z(0){}
   MyClass(int _x,int _y,int _z):x(_x),y(_y),z(_z){} //用于单个声明
   void set(int _x,int _y,int _z)
   {
     X = _x;
     Y = _y;
     Z = _z;
   }
 };

标准的初始化构造函数仍然存在,所以我仍然可以正常初始化它,如果我不需要超过一个,但否则,我有一个set方法设置在构造函数中初始化的所有variables。 因此,我可以做这样的事情:

 int len = 25;
 MyClass list = new MyClass [len];
 for(int i = 0; i <len; i ++)
  列表[I] .SET(1,2,3);

这工作正常,自然stream动,没有使代码看起来混乱。


现在,这是我想知道如何声明一个需要初始化的对象数组的答案。

对于你来说,你试图给出一系列的汽车身份,我想你总是想要独一无二的。 你可以用我上面解释的方法来实现,然后在for循环中使用i+1作为发送给set方法的参数 – 但是从我在你的注释中读到的内容来看,你似乎希望id更内部发起,所以默认情况下,每辆车都有一个唯一的ID,即使别人用你的Car

如果这是你想要的,你可以使用一个静态成员:

一stream的汽车
 {
   static int current_id;
   int id;
上市:
   Car():id(current_id ++){}

   int getId(){return id;  }
 };
 int Car :: current_id = 1;

 ...

整车= 10;
 car * carlist =新车[cars];

 for(int i = 0; i <cars; i ++)
   cout << carlist [i] .getId()<<“”;  //打印“1 2 3 4 5 6 7 8 9 10”

通过这种方式,您不必担心启动身份,因为它们是在内部pipe理的。

您可以随时创build指向数组的指针,指向汽车对象,然后按照需要在for循环中创build对象,并将其地址保存在数组中,例如:

 #include <iostream> class Car { private: Car(){}; int _no; public: Car(int no) { _no=no; } void printNo() { std::cout<<_no<<std::endl; } }; void printCarNumbers(Car *cars, int length) { for(int i = 0; i<length;i++) std::cout<<cars[i].printNo(); } int main() { int userInput = 10; Car **mycars = new Car*[userInput]; int i; for(i=0;i<userInput;i++) mycars[i] = new Car(i+1); 

注意新的方法!

  printCarNumbers_new(mycars,userInput); return 0; } 

所有你必须改变新的方法是处理汽车指针比静态对象在参数和调用方法printNo()例如:

 void printCarNumbers_new(Car **cars, int length) { for(int i = 0; i<length;i++) std::cout<<cars[i]->printNo(); } 

在主要结束是好删除所有这样的dynamic分配的内存

 for(i=0;i<userInput;i++) delete mycars[i]; //deleting one obgject delete[] mycars; //deleting array of objects 

希望我帮助,欢呼!

在C ++ 11的std::vector你可以使用emplace_back就地实例化元素:

  std::vector<Car> mycars; for (int i = 0; i < userInput; ++i) { mycars.emplace_back(i + 1); // pass in Car() constructor arguments } 

瞧!

Car()默认构造函数从不调用。

mycars超出范围时,删除将自动发生。

要解决的一个方法是给出一个静态工厂方法来分配数组,如果由于某种原因,你想给build设者私人。

 static Car* Car::CreateCarArray(int dimensions) 

但是,为什么你保持一个构造函数公开和其他私人?

但无论如何,还有一种方法是使用默认值声明公共构造函数

 #define DEFAULT_CAR_INIT 0 Car::Car(int _no=DEFAULT_CAR_INIT); 

我不认为有types安全的方法可以做你想要的。

您可以使用新的就地操作员。 这会有点可怕,我build议你留在工厂里。

 Car* createCars(unsigned number) { if (number == 0 ) return 0; Car* cars = reinterpret_cast<Car*>(new char[sizeof(Car)* number]); for(unsigned carId = 0; carId != number; ++carId) { new(cars+carId) Car(carId); } return cars; } 

并定义一个相应的销毁以匹配在此使用的新的。

我的方式

 Car * cars; // else were extern Car * cars; void main() { // COLORS == id cars = new Car[3] { Car(BLUE), Car(RED), Car(GREEN) }; }