2010-04-27 2 views
1

사용자 정의 클래스에 대해 멤버 함수가 정의되지는 않았지만 사용되었습니다. 따라서 다음과 같은 코드가 있습니다.C++ (생성자, 소멸자, 연산자 =, 복사 생성자)의 클래스의 기본 멤버 함수에 문제가 발생했습니다. (기본 ctor, dtor, copy ctor)

class AA 
{ 
}; 

void main() 
{ 
    AA a; 
    AA b(a); 
    a = b; 
} 

이 코드는 정상적으로 작동합니다. 컴파일러 오류가 없다는 뜻입니다. 그러나 다음 코드는 ....

class AA 
{ 
    int member1; 
    int member2; 
}; 

이 코드는 변수 "a"가 iniltialized되지 않고 사용되기 때문에 런타임 오류가 발생합니다 !!!

내 질문은 이것입니다 : 우리가 int를 인스턴스화 할 때, 그것은 가치가 있습니다. 그렇다면 왜 기본 생성자가 작동하지 않고이 두 정수를 사용하여 변수 "a"를 초기화합니까?

편집 : 플랫폼 : Windows Vista, 컴파일러 : Visual Studio 2008 컴파일러; 플래그 : 기본값

+2

어떤 종류의 런타임 오류가 발생합니까? – Glen

+0

두 번 째 작성 : 변수 "a"가 iniltialized없이 사용됩니다 !!! – Narek

+0

컴파일러에서 "/ WX"(경고로 경고 처리) 속성을 설정할 수 있습니까? –

답변

6

컴파일러에서 합성 된 기본 생성자는 생성자가있는 모든 클래스 멤버의 기본 생성자를 호출합니다. 그러나 정수에는 생성자가 없으므로 초기화되지 않습니다. 그러나, 이것이 런타임 오류를 일으킬 것이라고 믿기가 어렵습니다.

그 변수를 초기화하려면 :

class AA { 
    public: 
    AA() : member1(0), member2(0) {} 
    private: 
    int member1; 
    int member2; 
}; 
+0

+1, 회원 변수를 초기화하는 노력의 수준은 최소화하고 훨씬 깨끗합니다. – Robb

0

어떤 플랫폼입니까? 컴파일러? 컴파일러 플래그? 초기화 상태를 검사하는 일반적인 C++에는 아무 것도 없으므로 추가 검사를 추가해야합니다.

0

사실, 기본 및 복사 생성자가 일을. 그러나 cpp에서 초기화되지 않은 변수에는 실제로 가비지가 들어 있습니다. 따라서 오류가 발생합니다 (int member1, int member2에 휴지통이 포함되어 있으며이 휴지통을 b 개체에 할당하려고합니다).

+0

그것은 내가 할당 한 값이 쓰레기라고 어떻게 이해합니까 ?? – Narek

+0

@Narek 일부 C++ 컴파일러는 디버깅을위한 코드를 빌드 할 때이를 감지 할 수있는 특수 값 (Visual C++은 0xCDCDCDCD를 사용한다고 생각합니다)으로 초기화되지 않은 변수를 채 웁니다. 내 추측은 컴파일러 생성 된 복사 생성자가이 오류 유형을 잡으려고 복사하는 개체의 필드를 확인합니다. 릴리즈 빌드에서는 이것에 의존하지 마십시오. 릴리즈 빌드에서는 이미 그 메모리에 있던 데이터가 모두 포함됩니다. –

+0

0xCDCDCDCD는 스택 (로컬 변수)이 아닌 힙 할당을 채우기 위해 사용됩니다. 그리고 0xCDCDCDCD 값이있는 int는 유효합니다 (-842150451). 0xCDCDCDCD가있는 포인터를 역 참조하는 것은 int를 사용하지 않고 트랩합니다. – progrmr

0

첫째, 초기화하지 않고 int를 인스턴스화하면 불확정 값을 갖습니다. 기본 제공 기본 형식에는 생성자가 없습니다.

두 번째로, 해당 코드는 런타임 오류를 생성해서는 안됩니다. 자동 생성 된 복사 생성자와 대입 연산자에서 불확정 int 값을 복사합니다. 초기화되지 않은 변수가 사용 중임을 경고하는 컴파일러를 생성해야합니다.

셋째 주에 대한 서명이 잘못 - 올바른 서명이 진짜 런타임 오류가 아닙니다보기의 실용적인 관점에서, 첫째

int main(void) 
+0

int main() 대신 int main (void)을 쓸 때 무언가 변경됩니까 ??? – Narek

+0

C++ 표준에 따라 정확 해집니다. 그렇지 않으면 많이 변경되지 않지만 반환 값을 사용하여 성공 또는 실패를 지정하여 "체인화"프로그램에 유용합니다. –

+3

Narek, int main (void); 및 int main(); 하지만 무효 메인()을 사용해서는 안됩니다 –

1

입니다. 이것은 개발 환경의 내장 디버깅 기능입니다. 컴파일러는 초기화되지 않은 값을 읽었을 때 상황을 포착하려고 시도합니다.이 값은 여러분의 경우에 발생합니다.

두 번째로 int을 "인스턴스화"하면 의 값은이 아닙니다. 좀 더 정확하게 말하자면, 그것은 안정적이지 않을 수있는 미정의 값을 포함합니다 (동일한 초기화되지 않은 변수를 여러 번 읽음으로써 다른 값을 얻을 수 있습니다). 이론적으로 초기화되지 않은 int 변수를 읽는 것은 불법 ("트랩") 표현을 포함 할 수 있으므로 정의되지 않은 동작을 발생시킵니다. 실제로 개발 환경에서 생성 된 "런타임 오류"는 정의되지 않은 동작의 형태로 인식 할 수 있습니다.

+0

함수 호출 내에서 초기화되지 않은 지역 변수는 안정적이지만 (변하지는 않음) 함수에 대한 각 호출은 지역 변수를 다시 할당하며 그 시점에서 스택 메모리에있는 모든 값을 가져옵니다. 또한 int는 트랩 표현을 포함 할 수 없으며 int의 모든 값이 유효합니다. 초기화되지 않은 경우 얻을 수있는 값을 알지 못합니다. – progrmr

+0

@ kk6yb : 아니요, 틀 렸습니다. 첫째, 일반적인 경우에는 안정적이지 않습니다. 언어는 그러한 보증을하지 않으며 실제로 실제로 불안정성은 실제로 재현 할 수 있습니다. 불안정성은 실제로 변수가 CPU 레지스터에 의해 표현되고 그 값을 "값 수명"(즉, 레지스터가 실제로 다른 변수에 사용될 때)에 액세스 할 때 발생합니다. 스택 메모리는 일반적인 경우에 스택 메모리와 관련이 거의 없습니다. – AnT

+0

@ kk6yb : 둘째, 트랩 표현을 포함 할 수없는 C++의 유일한 유형은 '서명되지 않은 char'입니다 (즉, 모든 비트 패턴이 유효합니다). 'int'를 포함한 다른 모든 타입은 트랩 표현을 포함 할 수 있습니다. – AnT

관련 문제