c++ 생성자에 반환형 없나요?

익명 사용자의 이미지

제가 생각했을때 컴파일 타임에

컴파일러가 추가시킬거 같은데

그래야 Class c = Class();

이런 생성자 반환값 대입 문장이 유효하지 않나요?

함수가 반환형이 아예 없이도 이런 대입문장이

내부적으로 원래 가능한가요?

 의 이미지

뭔가 오해가 있는 것 같군요.

위 코드에서 Class();는 클래스 Class의 생성자를 직접 호출하는 것이 아닙니다.

C++ 표준에서 이 표현식은 Explicit type conversion (functional notation)이며, Function call과는 다릅니다.
이 명시적 타입 변환의 결과로 Class타입 prvalue 임시 객체가 하나 생성됩니다.
그 과정에서 Class의 생성자가 간접적으로 호출되는 것이지요.
따라서 "생성자를 호출하여 그 반환값을 받는 것"이라는 해석은 잘못된 것입니다.

그 이후에, 앞서 생성된 임시 객체를 초기치 삼아 Class타입 변수 c가 이동/복사 생성됩니다.

물론 그렇다고 컴파일러가 실제로 임시 객체를 생성하고, c를 이동/복사 생성하고, 임시 객체를 파괴하는 삼중고의 코드를 만들지는 않을 겁니다.
제시하신 코드는 C++ 표준이 명시적으로 허용하는 최적화 패턴 copy elision의 모범적인 적용대상이기 때문이죠.
쓸만한 컴파일러라면 당연히 c에 바로 생성자를 호출하여 초기화하는 코드를 생성하기 마련입니다.

글쓴이의 이미지

감사합니다..

Anti-Lock의 이미지

생각 못했던 부분이네요.
이제까지 저는 '생성자 호출(클래스인 경우)'이나
그와 유사한 동작(프리미티브 타입일 경우)을 하는 것으로 알았습니다.

다음과 같은 구문
int j = int(100);
int k = int(123.456);
은 캐스팅되는것으로 생각해도 무리가 없습니다.

그런데, 다음과 같은 구문을 볼때..
int i = int();
이 구문에서 i가 초기값 0을 갖는다는 것은 무엇 때문일까요..?
단순히 캐스팅 되는것은 아닌것 같은데요...
오히려, 프리미티브 타입이지만 인자없는 생성자가 있고,
그것이 호출되도록 하는(간접적이든 직접적이든) 구문 같네요. (<- 이부분은 C++의 내부적인 규칙 같아 보입니다)

 의 이미지

아뇨.
여전히 Explicit type conversion (functional notation) 입니다.

T가 simple-type-specifier이거나 typename-specifier일 경우, 표현식 T()은 Explicit type conversion (functional notation)으로서, value-initialized 되는 prvalue를 생성하게 됩니다.

여기서 T가 int라면 value-initialize는 zero-initialize와 같고, 따라서 0으로 초기화됩니다. 결과적으로 변수 i가 0으로 초기화되는 것입니다.

DarkSide의 이미지

위에서 친절하게 설명해 주셨는데, 왜 다시 캐스팅이나 다른 말이 나오는지 모르겠네요.

Anti-Lock의 이미지

위에서 친절하게 설명해 주셨는데, 왜 다시 캐스팅이나 다른 말이 나오는지 모르겠네요.
변명하자면 '명시적 타입 변환'이라고 되어 있어서 그렇게 생각한 것입니다.