C++ 没有默认构造函数的对象数组初始化
有没有一种方法可以在不公开Car()构造函数的情况下进行初始化?没有 但是瞧!如果您像应该的那样使用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 #
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;i cout您始终可以创建一个指针数组,指向汽车对象,然后根据需要在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)
};
}