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

C++ 没有默认构造函数的对象数组初始化,c++,arrays,constructor,C++,Arrays,Constructor,有没有一种方法可以在不公开Car()构造函数的情况下进行初始化?没有 但是瞧!如果您像应该的那样使用std::vector(永远不要使用new[]),那么您可以精确地指定元素的构造方式* *嗯,差不多。您可以指定要制作副本的值 像这样: cartest.cpp: In function ‘int main()’: cartest.cpp:5: error: ‘Car::Car()’ is private cartest.cpp:21: error: within this context #

有没有一种方法可以在不公开Car()构造函数的情况下进行初始化?

没有

但是瞧!如果您像应该的那样使用
std::vector
(永远不要使用
new[]
),那么您可以精确地指定元素的构造方式*

*嗯,差不多。您可以指定要制作副本的值


像这样:

cartest.cpp: In function ‘int main()’:
cartest.cpp:5: error: ‘Car::Car()’ is private
cartest.cpp:21: error: within this context
#包括
#包括
班车
{
私人:
Car();//如果你不使用它,你可以将它声明为私有
国际(无);
公众:
汽车(国际编号):
_否(否)
{
//使用初始化列表初始化成员,
//而不是构造函数主体来分配它们
}
void printNo()
{
//使用空格,它使内容更容易阅读

std::cout不,没有。新表达式只允许默认初始化或根本不允许初始化


解决方法是使用
运算符new[]
分配原始内存缓冲区,然后使用placement new和非默认构造函数在该缓冲区中构造对象。

一种解决方法是,如果出于某种原因,您希望将构造函数设为私有,则提供一个静态工厂方法来分配数组

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());
} 
但是为什么你要让一个构造函数保持公共,而另一个保持私有

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

static Car*  Car::CreateCarArray(int dimensions)

我认为没有类型安全的方法可以满足您的需要。

您可以创建一个指针数组

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

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

static Car* makeArray(int length){
    return new Car[length];
}
Car*createCars(无符号编号)
{
如果(数字==0)
返回0;
Car*cars=重新解释(新字符[sizeof(Car)*编号];
对于(无符号carId=0;
carId!=数字;
++(加勒比)
{
新车(cars+carId)车(carId);
}
返回车辆;
}

并定义相应的销毁,以便与此中使用的新位置相匹配。

您可以这样使用placement new:

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;
}
等级车
{
国际(无);
公众:
车辆(内部编号):\车辆编号(内部编号)
{
}
};
int main()
{
void*raw_memory=operator new[](NUM_CARS*sizeof(Car));
Car*ptr=静态转换(原始存储器);
对于(int i=0;i=0;--i){
ptr[i]。~Car();
}
操作员删除[](原始内存);
返回0;
}
<更有效的C++——Scott Meyers的引用:

第4项-避免不必要的默认构造函数好问题。我有同样的问题,在这里找到了。真正的答案是,@Dan Paradox,没有标准的语法方法。因此,所有这些答案都是解决这个问题的多种选择

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

class-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){}//用于单个声明
空集(int x,int y,int z)
{
x=x;
y=_y;
z=z;
}
};
标准的初始化构造函数仍然存在,因此如果我不需要多个构造函数,我仍然可以正常初始化它,但是如果不需要,我有一个
set
方法来设置构造函数中初始化的所有变量。因此,我可以这样做:

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;
}
int len=25;
MyClass list=新的MyClass[len];
对于(int i=0;i
这可以很好地工作并自然流动,不会使代码看起来混乱


对于那些想知道如何声明需要初始化的对象数组的人来说,这就是我的答案

具体来说,您试图给出一组cars标识,我想您希望这些标识总是唯一的。您可以使用我在上面解释的方法来实现这一点,然后在
For
循环中使用
I+1
作为发送到
set
方法的参数-但是从我在您的注释中看到的情况来看,您似乎nt更内部启动的id,因此默认情况下,每辆车都有一个唯一的id,即使其他人使用您的类

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

等级车
{
静态int当前_id;
int-id;
公众:
Car():id(当前_id++){
int getId(){return id;}
};
int Car::当前_id=1;
// ...
int cars=10;
Car*carlist=新车[汽车];
对于(int i=0;icout您始终可以创建一个指针数组,指向汽车对象,然后根据需要在for循环中创建对象,并将其地址保存在数组中,例如:

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;
}
在这个新方法中,您所要做的就是将汽车作为指针而不是静态对象来处理 在参数中和调用方法printNo()时 例如:

  printCarNumbers_new(mycars,userInput);


  return 0;
}    
void printCarNumbers\u new(车**车,整数长度)
{

对于C++11的
std::vector
中的(int i=0;i),您可以使用以下命令就地实例化元素:

std::vector mycars;
对于(int i=0;i

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

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

myway

  std::vector<Car> mycars;

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

当然,我们会使用
std::vector
,这样做。但是+1表示正确性。如何使用运算符new[]分配原始内存?任何可以解释这一点的链接?@Dan Paradox:Chan的答案中有一个例子。ITYM新表达式的数组形式只允许默认初始化,
A*A=new A(args)
很好。这个答案也可以在C++11中更新。我把它设为Car()私有,因为我想避免复制constructor@Dan:但那不是复制构造函数。@GMan
#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;
}    
void printCarNumbers_new(Car **cars, int length)
{
    for(int i = 0; i<length;i++)
         std::cout<<cars[i]->printNo();
}
for(i=0;i<userInput;i++)
  delete mycars[i];      //deleting one obgject
delete[] mycars;         //deleting array of objects
  std::vector<Car> mycars;

  for (int i = 0; i < userInput; ++i)
  {
      mycars.emplace_back(i + 1); // pass in Car() constructor arguments
  }
Car * cars;

// else were

extern Car * cars;

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