기본 생성자없이 객체 배열 초기화
#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;
}
자동차 배열을 만들고 싶지만 다음 오류가 발생합니다.
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
}
추가 기능 :
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
정말 범위를 나타내는 두 반복자에 동의 다르게 설계되어야한다.
다음과 같이 새 배치를 사용할 수 있습니다.
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-불필요한 기본 생성자를 피하십시오.
포인터 배열을 만들 수 있습니다.
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 () 생성자는 공용 일 필요가 없습니다. 배열을 만드는 클래스에 정적 메서드를 추가합니다.
static Car* makeArray(int length){
return new Car[length];
}
좋은 질문. 저도 같은 질문을했는데 여기서 찾았습니다. 진짜 대답은 @ 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 ++) 목록 [i] .set (1,2,3);
이것은 코드를 혼동하지 않고 잘 작동하고 자연스럽게 흐릅니다.
이제 초기화해야 할 객체 배열을 선언하는 방법을 궁금해하는 사람들에 대한 대답입니다.
구체적으로 말하면, 당신은 자동차에 대한 일련의 신원을 부여하려고하는데, 저는 당신이 항상 독특하고 싶어한다고 생각합니다. 위에서 설명한 내 방법으로 할 수 있으며 for
루프 i+1
에서 set
메서드로 보낸 인수로 사용할 수 있습니다. 하지만 귀하의 의견에서 읽은 내용에서 ID를 더 내부적으로 시작하려는 것 같습니다. 다른 사람이 클래스를 사용하더라도 기본적으로 각 Car에는 고유 한 ID가 있습니다 Car
.
이것이 원하는 경우 정적 멤버를 사용할 수 있습니다.
클래스 자동차 { static int current_id; int id; 공공의: 자동차 () : id (current_id ++) {} int getId () {반환 ID; } }; int Car :: current_id = 1; ... int cars = 10; Car * carlist = 새 자동차 [자동차]; for (int i = 0; i <자동차; i ++) cout << carlist [i] .getId () << ""; // "1 2 3 4 5 6 7 8 9 10"인쇄
이렇게하면 ID가 내부적으로 관리되기 때문에 시작에 대해 전혀 걱정할 필요가 없습니다.
아니, 없습니다. New-expression은 기본 초기화 만 허용하거나 초기화를 전혀 허용하지 않습니다.
해결 방법은를 사용하여 원시 메모리 버퍼를 할당 operator new[]
한 다음 기본이 아닌 생성자와 함께 place-new를 사용하여 해당 버퍼에서 객체를 생성하는 것입니다.
언제든지 car 객체를 가리키는 포인터 배열을 만든 다음 for 루프에서 객체를 만들고 배열에 주소를 저장할 수 있습니다. 예를 들면 다음과 같습니다.
#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();
}
main 끝에서 이와 같이 동적으로 할당 된 모든 메모리를 삭제하는 것이 좋습니다.
for(i=0;i<userInput;i++)
delete mycars[i]; //deleting one obgject
delete[] mycars; //deleting array of objects
내가 도왔 으면 좋겠다, 건배!
In C++11's std::vector
you can instantiate elements in-place using emplace_back
:
std::vector<Car> mycars;
for (int i = 0; i < userInput; ++i)
{
mycars.emplace_back(i + 1); // pass in Car() constructor arguments
}
Voila!
Car() default constructor never invoked.
Deletion will happen automatically when mycars
goes out of scope.
One way to solve is to give a static factory method to allocate the array if for some reason you want to give constructor private.
static Car* Car::CreateCarArray(int dimensions)
But why are you keeping one constructor public and other private?
But anyhow one more way is to declare the public constructor with default value
#define DEFAULT_CAR_INIT 0
Car::Car(int _no=DEFAULT_CAR_INIT);
I don't think there's type-safe method that can do what you want.
My way
Car * cars;
// else were
extern Car * cars;
void main()
{
// COLORS == id
cars = new Car[3] {
Car(BLUE),
Car(RED),
Car(GREEN)
};
}
You can use in-place operator new. This would be a bit horrible, and I'd recommend keeping in a factory.
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;
}
And define a corresponding destroy so as to match the new used in this.
참고URL : https://stackoverflow.com/questions/4754763/object-array-initialization-without-default-constructor
'IT TIP' 카테고리의 다른 글
C # UserControl에 Dispose 기능을 어떻게 추가합니까? (0) | 2020.12.10 |
---|---|
Ruby on Rails에서 연결을 통해 has_many를 어떻게 주문합니까? (0) | 2020.12.10 |
JSF 2.0에서 세션을 무효화하는 방법은 무엇입니까? (0) | 2020.12.10 |
서버 측 브라우저 감지? (0) | 2020.12.10 |
Ruby-첫 번째 하위 문자열을 다른 문자열로 교체 (0) | 2020.12.10 |