Dan*_*dox 60 c++ arrays constructor
#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;
}
Run Code Online (Sandbox Code Playgroud)
我想创建一个汽车阵列,但我收到以下错误:
cartest.cpp: In function ‘int main()’:
cartest.cpp:5: error: ‘Car::Car()’ is private
cartest.cpp:21: error: within this context
Run Code Online (Sandbox Code Playgroud)
有没有办法在不使Car()构造函数公开的情况下进行初始化?
Cha*_*han 62
您可以像这样使用placement-new:
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;
}
Run Code Online (Sandbox Code Playgroud)
更有效的C++参考 - Scott Meyers:
第4项 - 避免使用无偿的默认构造函数
GMa*_*ckG 42
不.
但是,瞧!如果您使用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
}
Run Code Online (Sandbox Code Playgroud)
附加功能:
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());
}
Run Code Online (Sandbox Code Playgroud)
注意printCarNumbers
确实应该以不同的方式设计,以接受表示范围的两个迭代器.
Squ*_*all 20
您可以创建一个指针数组.
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;
Run Code Online (Sandbox Code Playgroud)
要么
Car()构造函数不需要是公共的.向构建数组的类添加静态方法:
static Car* makeArray(int length){
return new Car[length];
}
Run Code Online (Sandbox Code Playgroud)
在 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
}
Run Code Online (Sandbox Code Playgroud)
瞧!
Car() 默认构造函数从未被调用。
当mycars
超出范围时,删除将自动发生。
好问题。我有同样的问题,在这里找到了。真正的答案是,@ Dan-Paradox,没有标准的语法方法。因此,所有这些答案都是解决问题的多种选择。
我自己阅读了答案,但并没有特别找到适合我个人惯例的答案。我可能会坚持使用的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){} //用于单个声明 无效集(int _x,int _y,int _z) { x = _x; y = _y; z = _z; } };
标准的初始化构造函数仍然存在,因此,如果我不需要多个初始化构造函数,我仍然可以正常对其进行初始化,但是如果不是这样,我可以使用一种set
方法来设置在构造函数中初始化的所有变量。因此我可以做这样的事情:
int len = 25; MyClass列表= new MyClass [len]; for(int i = 0; i <len; i ++) list [i] .set(1,2,3);
这可以正常工作并且自然地流动,而不会使代码看起来令人困惑。
对于那些想知道如何声明需要初始化的对象数组的人来说,这就是我的答案。
具体来说,您正在尝试提供一系列汽车标识,我想您应该一直保持独特。您可以使用上面说明的方法来执行此操作,然后在for
循环i+1
中将其用作发送给该set
方法的参数-但是从我在注释中所读取的内容来看,您似乎希望ID在内部进行更多初始化,因此通过默认情况下,即使其他人使用您的班级,每个Car也具有唯一的ID Car
。
如果这是您想要的,则可以使用静态成员:
类车 { 静态整数current_id; int id; 上市: Car():id(current_id ++){} int getId(){返回ID;} }; int Car :: current_id = 1; ... 整车= 10; Car * carlist =新车[cars]; for(int i = 0; i <汽车; i ++) cout << carlist [i] .getId()<<“”; //打印“ 1 2 3 4 5 6 7 8 9 10”
这样,由于身份是在内部进行管理的,因此您不必担心启动身份。
没有人评论过使用分配器来完成此任务的可能性。
#include <iostream>
#include <memory>
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++)
(cars+i)->printNo();
}
int main()
{
int userInput = 10;
std::allocator<Car> carAllocator;
// reserves space in memory for 10 car objects, but not construct them
Car *myCars = carAllocator.allocate(10);
Car *myCarsBegin = myCars; // begin of array myCars
for(int i =0; i < userInput; i++ ){
// effectively creates the class "Car" and initializes it
// myCars now points to the first car created
carAllocator.construct( myCars, i );
++myCars;
}
printCarNumbers(myCarsBegin,userInput);
// destroy the objects created
for( Car *carIterator = myCarsBegin; carIterator != myCars; ++carIterator )
carAllocator.destroy( carIterator );
return 0;
}
Run Code Online (Sandbox Code Playgroud)