2010-04-07 11 views
1

개체 배열을 만들 때 사용자 정의 형식의 경우이 배열의 모든 요소가 기본 생성자로 초기화되지만, 그렇지 않은 경우 기본 제공 형식의 배열을 만들면 어떨까요?기본값을 지정할 수 있습니까?

두 번째 질문 : 배열의 요소를 초기화하는 동안 사용할 기본값을 지정할 수 있습니까? 이와 같은 것 (유효하지 않음) :

char* p = new char[size]('\0'); 

배열과 관련된 또 다른 질문입니다. 사용자 정의 유형의 배열을 만들 때이 배열의 모든 요소가 기본값으로 초기화된다고 가정합니다. 왜 이런거야?

내장 유형의 배열이 기본값을 사용하여 요소를 초기화하지 않는 경우 사용자 정의 유형에 대해 왜 그런가?

어떻게 든 기본 구성을 회피하거나 우회하는 방법이 있습니까? 예를 들어 크기 10000의 배열을 만들면 10000 기본 생성자 호출을 강제로 수행하고 나중에 (다시) 덮어 쓸 데이터를 초기화하면 낭비되는 것 같습니다.

나는 동작이 일관성이 있어야하므로 모든 유형의 배열을 초기화하거나 초기화해야한다고 생각합니다. 그리고 내장 배열의 동작이 더 적절하다고 생각합니다.

+5

진지하게 - 표준 영어 질문을 쓰는 것이 어렵습니까? "elem"이라고 입력하고 있습니다. 및 "dflt ctor"모두 "요소"및 "기본 생성자"보다 훨씬 빠릅니까? 나는이 것을 영어 이해력에 맞게 편집하여 이해를 돕지 만, 다른 사람들이 당신의 질문이 무엇인지 이해하기 위해 열심히 일할 필요가 없다면 더 나은 답을 얻을 수 있습니다. –

+0

@atch : 나는 그것을 내 대답으로 편집했다. –

+0

그리고 심각하게도 elem, elems, ctor, dtor 및 dflt ctor와 같은 꽤 일반적인 약어를 이해하는 데 문제가있는 사람은 없습니다 (물론 제외). 심지어 당신은 POD UDT 등을 사용하고 있습니다. –

답변

0

뭔가 (유효하지 않음) :

은 내가 아는 한 그것은 완벽하게 유효합니다. 음 완전히,하지만 당신은 제로 intialized 문자 배열을 얻을 수 없습니다 :

#include <iostream> 
#include <cstdlib> 

int main(int argc, char* argv[]) 
{ 
    //The extra parenthesis on the end call the "default constructor" 
    //of char, which initailizes it with zero. 
    char * myCharacters = new char[100](); 
    for(size_t idx = 0; idx != 100; idx++) { 
     if (!myCharacters[idx]) 
      continue; 
     std::cout << "Error at " << idx << std::endl; 
     std::system("pause"); 
    } 
    delete [] myCharacters; 
    return 0; 
} 

이 프로그램은 어떠한 출력을 생성하지 않습니다.

배열과 관련된 또 다른 질문입니다. 나는 사용자 정의 타입의 배열을 만들 때 모든 elem이라는 사실을 알고 있다고 가정합니다. 이 배열의 기본값으로 먼저 초기화됩니다 왜?

new로 할당 된 각 요소를 전문화하는 좋은 구문 방식이 없기 때문에. 대신 벡터를 사용하고 미리 reserve()를 호출하면이 문제를 피할 수 있습니다. 벡터는 메모리를 할당하지만 생성자는 벡터로 push_back 할 때까지 호출되지 않습니다. 어쨌든 new'd 메모리 처리는 거의 항상 예외 안전이 아니기 때문에 사용자 관리 배열 대신 벡터를 사용해야합니다.

나는 동작이 일관성이 있어야하므로 모든 유형의 배열을 초기화하거나 초기화하지 않아야한다고 생각합니다. 그리고 내장 배열의 동작이 더 적절하다고 생각합니다.

글쎄, 당신이 표준을위한 제안서를 작성할 수 있다면 좋은 구문을 생각해 볼 수 있습니다.

개체 배열을 만들 때 사용자 정의 형식의 경우이 배열의 모든 요소가 기본 생성자로 초기화되지만, 그렇지 않은 경우 기본 제공 형식의 배열을 만들면 어떨까요?
배열을 사용하는 동안이 항목의 또 다른 질문입니다. 사용자 정의 유형의 배열을 만들 때이 배열의 모든 요소가 기본값으로 초기화된다고 가정합니다. 왜 이런거야?
내장 유형의 배열이 기본값을 사용하여 요소를 초기화하지 않는 경우 사용자 정의 유형에 대해 왜 그런가?
사용자 정의 유형은 생성자가 호출 될 때까지 유효하지 않습니다. 내장 유형은 생성자가 호출되지 않은 경우에도 항상 유효합니다.

두 번째 질문 : 배열의 요소를 초기화하는 동안 사용할 기본값을 지정할 수 있습니까? 이와 같은 것 (유효하지 않음) :
이 질문에 대한 답변

어떻게 든 기본 구성을 회피하거나 우회하는 방법이 있습니까? 예를 들어 크기 10000의 배열을 만들면 10000 기본 생성자 호출을 강제로 수행하고 나중에 (다시) 덮어 쓸 데이터를 초기화하면 낭비되는 것 같습니다.
예, 위에서 설명한대로 벡터를 사용할 수 있습니다.

+0

어떻게 컴파일 했습니까, 그것이 유효하다는 말입니까? –

+0

@atch : 죄송합니다.'char'는 이와 같은 복사 생성자를 제공하지 않는다는 것을 깨달았습니다. 모든 생성자를 0으로 초기화하는 기본 생성자 구문을 사용하는 예제에서 편집했습니다. –

+0

그리고 구문에 관하여 : 저는 제가 제시 한 구문이 꽤 괜찮다고 생각합니다. –

0

현재 (새로운 C++ 0x를 사용하지 않는 한) C++은 인수를 취하지 않는 생성자를 호출합니다. myClass::myClass(). 그것을 초기화하려면 변수를 초기화하는 이와 같은 생성자를 구현하십시오. 예 : 이 같은


class myChar { 
    public: 
     myChar(); 

     char myCharVal; 
}; 

myChar::myChar(): myCharVal('\0') { 
} 
+0

이렇게하면 런타임 패널티가 발생합니다. 대부분의 클래스/구조체는 엄격하게 필요하지 않더라도 항상 네이 키드 문자와 다른 정렬 규칙을 갖습니다. 예를 들어, x86에서 클래스의 너비는 1이 아니라 4 바이트입니다. –

+0

죄송합니다. 편집을 놓쳤습니다.두 번째 질문으로, 사용자 정의 클래스에서 변수를 초기화하지 않으면 컴파일러에 따라 달라집니다. 일부 컴파일러는 최적화와 같은 컴파일러 옵션을 사용하지 말라고하지 않는 한 변수를 0으로 설정하고 다른 변수는 아무 것도하지 않도록 설정합니다. 따라서 10,000 요소의 배열을 설정하면 아무 일도하지 않아도됩니다. – Warpspace

+0

#pragma pack 설정을 사용하여 컴파일러에서 채워야하는 패딩을 지정할 수 있다고 생각하지만 (필자가 직접 시도한 적은 없지만) 클래스가 "Plain"인 경우 항상 배열을 긴밀하게 묶는 방법이 있습니다. Old Data "(가상 기능처럼 멋진 기능을하지 마십시오). – Warpspace

0

C++ 철학은 - 필요없는 것을 지불하지 않습니다.

그리고 행동이 꽤 통일 된 것 같습니다. UDT에 기본 생성자가 없으면 아무 것도 실행되지 않고 동작은 기본 생성자가없는 기본 제공 유형과 동일합니다.

+0

거의. 모든 UDT (심지어 POD 유형)에는 컴파일러가 제공하는 기본 생성자가 있습니다. 단지 POD 구조체라면 기본 생성자는 아무 것도 할 필요가 없지만 그럼에도 불구하고 문제가 있습니다. –

+0

그러나 dflt ctor를 제공하지 않으면 객체 배열을 만들 수 없습니다. 그리고 내가 필요로하지 않는 것에 대해 비용을 지불해서는 안된다는 철학이 있다면 왜 dflt ctor를 호출해야합니까? –

+0

"하지만 dflt ctor를 제공하지 않으면 개체 배열을 만들 수 없습니다." <- 네, 그렇습니다. 잠시만 내 대답을 편집 해 보겠습니다. –

0

개체 배열을 만들 때 사용자 정의 형식의 경우이 배열의 모든 요소는 기본 생성자로 초기화되지만, 그렇지 않은 경우 기본 제공 형식의 배열을 만들면 ?

그러나 개체의 기본 생성자가 아무 것도 수행하지 않으면 여전히 초기화되지 않습니다.

class X 
{ 
    public: 
     char y; 
} 
X* data = new X[size]; // defaut constructor called. But y is still undefined. 

그리고 두 번째 질문 :이 배열의 요소를 초기화하는 동안 사용되는 기본 값을 지정할 수 있습니까? >이 (유효하지 않음)와 같은 뭔가 :

예 :

char    data1[size] = { 0 }; 
std::vector<char> data2(size,0); 
char*    data3 = new char[size]; 
memset(data3,0,size); 

어떻게 든이 기본 구성을 우회/피할 수있는 방법이 있나요? 예를 들어 크기 10000의 배열을 만들면 10000 기본 생성자 호출을 강제로 수행하고 나중에 (다시) 덮어 쓸 데이터를 초기화하면 낭비되는 것 같습니다.

예. std :: vector를 사용하십시오.

생성자를 호출하지 않고 필요한 모든 요소의 공간을 예약 할 수 있습니다.

std::vector<char> data4; 
data4.reserve(size); 
1

이것이 기본 제공 유형이 C++에서 작동하는 방식입니다. 그것들을 초기화하기 위해서 명시적인 초기화자를 제공해야한다. 그렇지 않으면 개체가 초기화되지 않은 상태로 유지됩니다. 이 동작은 배열과 관련이 없습니다. 독립 실행 형 개체는 정확히 동일한 방식으로 동작합니다.

여기서 한 가지 문제는 new[]을 사용하여 배열을 만들 때 이니셜 라이저 (현재 언어 버전에서)를 제공하는 옵션이 매우 제한된다는 것입니다. 사실, 당신이 제공 할 수있는 유일한 초기화는 char 유형 (또는 다른 스칼라 형)의 () 초기화가 당신이 뭘하려 부수적 인 제로 초기화가 발생합니다 경우 빈 ()

char* p = new char[size](); 
// The array is filled with zeroes 

입니다 해야 할 것.

물론 원하는 기본값이 0이 아니면 운이 좋지 않습니다. 즉, 나중에 new[] -ed 어레이의 요소에 명시 적으로 기본값을 지정해야한다는 의미입니다.

사용자 정의 기본 생성자가있는 유형의 배열에 대한 기본 생성자 호출을 사용하지 않도록 설정하는 것과 같이 일반적으로 new[]을 사용하여이를 수행 할 수있는 방법은 없습니다. 그러나 자신의 배열 구성 프로세스 (예 : std::vector의 경우)를 구현하여이 작업을 수행 할 수 있습니다. 먼저 전체 배열에 원시 메모리를 할당 한 다음 원하는 방식으로 요소를 하나씩 수동으로 구성합니다. 표준 라이브러리는 그 목적을 위해 특별히 고안된 수많은 프리미티브를 제공합니다. 여기에는 std::allocator이 포함되며 uninitialized_copy, uninitialized_fill 등과 같은 기능이 포함됩니다.

관련 문제