a() = 10; 은 뭘 의도하시고 하신건지 -_-
= 앞에는 변수가 들어가야 하는데 a()가 리턴한 값은 변수가 아니잖아요. 이건 const 와는 관련 없는 사항입니다.
리턴 값에 const를 붙이면 리턴한 값을 리턴 받은 곳에서 변형시키지 않을 거라는걸 컴파일러에게 알려줘서, 프로그래머가 혹시나 실수로 고치려고 하는 걸 막아주죠.
그 밖에도 const T& 형태로 클래스의 변수를 리턴해, 리턴하는 값이 클래스나 스트럭쳐 일 때, 임시 생성자와 같은 쓸데 없는 연산이 생기지 않게도 해줄 수 있고요.
const도 어디에 붙이느냐에 따라 역할이 달라지니 이것도 좀 공부하시는게 좋을거 같고요.
+ 에 const를 리턴하는 건 좀 아닌거 같은데 -_-
대충 Complex의 +를 구현해보자면
class Complex
{
public:
float m_fReal, m_fImaginary;
Complex operator + ( const Complex& rhs )
{
return Complex( m_fReal + rhs.m_fReal, m_fImaginary + rhs.m_fImaginary );
}
}
이런식으로 구현해야 + 가 리턴한 Complex를 계속 다음 연산에 쓸 수 있겠죠?
2006.11.18 22:48:25 (*.252.125.45)
evax
답변 감사드림니다. 제가 좀 질문을 자세히 적지 않은듯 하네요
음 a() = 10; 은 int a(void); 의 경우에 const를 안 붙여줘도 리턴값은 상수가 아닌가? 하는 제 생각을 저렇게 확인했다는 의도로 쓴거구요-_-a;;...
리턴값이 레퍼런스면 당연히 const가 의미가 있겠지만 레퍼런스가 아닌경우에는 왜 const를 쓰는지 그 의미를 몰라서 한 질문입니다.
저 const Complex operator +(const Complex &T) 는 winapi.co.kr에서 연산자 오버로딩 부분에서 저런식으로
되어있던데 설명을 읽다보니 이런 질문을 하게 되었습니다.
음 그런데 리턴값이 const라도 말씀하신 경우에도 계속 다음 연산에 쓸수 있는데요...
2006.11.19 00:04:28 (*.47.126.166)
음..
제가 잘 모르고 있었습니다. const Complex operator + 로 정의되어 있으니
Complex a = b + c; 같은건 안될줄 알았는데 되네요.
b + c 에서 const Complex 가 생성되고 이것을 Complex a 에 대입하나 봅니다. const 는 non-const 에 대입할 수 있으니까요.
const Complex a ( 10.0f, 20.0f );
Complex b = a와 같은 원리인 것 같습니다. non-const 에 const를 대입하는 거요.
( 처음에는 Complex a = b + c;를 하면 copy constructor 가 불릴줄 알았는데, 그것도 아니더군요. -_- 똘똘한 컴파일러 -0- const 가 그냥 의미 없어지는 것 같습니다. )
const int a()
{
return 10;
}
에서도
int b = a();
가 가능한 걸로 보아 const int 를 int 에 대입해버린 것 같습니다.
const int a = 10;
int b = a;가 가능하니까요. 하지만 이건 a의 10을 사용하는게 아니라, b 에 복사된 10을 사용하는거니까 서로 다른 10이죠. a = 20은 당연히 안되지만, b = 20 은 당연히 되잖아요.
이런 리턴 값에서 const를 붙이는 건 낭비인 것 같네요. -0- 어차피 값을 복사해서 사용할 테니까요.
kallru// 음-_-; 전 말 그대로 상수일거라 생각했었습니다;;; 아니였군요 혹시 왜 상수가 아님에도 값을 할당할수 없는지도 알수 없을까요?
2006.11.20 04:10:47 (*.236.41.127)
gustwind
evax// 연산자의 리턴값을 const로 하는 이유는 b + c = a;와 같은 것을 막기 위해서입니다.
반드시 그래야 할 필요는 없지만, 연산자의 동작은 내장타입과 일치하도록 하는것이 직관적이기 때문입니다.
내장 타입의 경우 b + c = a;는 b + c의 결과가 rvalue이기 때문에 lvalue가 요구되는 =의 좌측에 사용될 수 없습니다.
사용자 정의 타입인 경우는 약간 다른데, C++ 표준문서를 보면 사용자 정의 타입 역시 value로 리턴될 때는 rvalue입니다.
하지만 리턴값에 const를 붙이지 않을 경우 b + c = a;가 성립되는데 이는 b + c의 결과가 lvalue이기 때문이 아니고,
b + c의 결과로 임시객체가 생성되고, 생성된 임시객체의 경우 멤버함수를 호출할 수 있기 때문입니다.
즉, 컴파일러에 의해 기본으로 생성된 operator=가 존재하므로 호출이 가능한 것이고, const를 붙인 경우는 const 접근제한이 걸린 operator=가 정의되어 있지 않기 때문에 에러가 발생합니다.
컴파일 에러코드를 비교해보면 VC++ 2003 기준으로 내장타입은 C2106(좌항이 lvalue가 아니다), 리턴값에 const를 붙인 사용자 정의 타입은 C2678(좌항 타입에 대해 정의된 연산자가 없다)인 것을 확인해 보실 수 있습니다.
const 접근제한을 갖는 operator=를 정의한다면 리턴값에 const를 붙인 경우 역시 b + c = a;가 컴파일됩니다.
저 역시 애매하던 부분이었는데 덕분에 찾아보느라 정리가 됐습니다.
음..// Complex a = b + c;에서 Copy Constructor가 호출되지 않는 것은 const가 의미없어지기 때문이 아닙니다.
원칙적으로 Complex a = b + c; 역시 Copy Consturctor가 호출됩니다만, 컴파일러 최적화가 활성화 된 경우 Return Value Optimization에 의해 Copy Constructor를 생략하고 operator+의 리턴값이 a의 주소로 직접 카피됩니다.
2006.11.20 09:34:36 (*.78.64.79)
음..
gustwind/ 네. 구글 뒤져보면서 const가 의미 없어지는게 아니란걸 알았습니다. 좋은 거 배웠네요. b + c = a 같은 건 생각도 안하고 있었는데 말이죠. -0-
= 앞에는 변수가 들어가야 하는데 a()가 리턴한 값은 변수가 아니잖아요. 이건 const 와는 관련 없는 사항입니다.
리턴 값에 const를 붙이면 리턴한 값을 리턴 받은 곳에서 변형시키지 않을 거라는걸 컴파일러에게 알려줘서, 프로그래머가 혹시나 실수로 고치려고 하는 걸 막아주죠.
그 밖에도 const T& 형태로 클래스의 변수를 리턴해, 리턴하는 값이 클래스나 스트럭쳐 일 때, 임시 생성자와 같은 쓸데 없는 연산이 생기지 않게도 해줄 수 있고요.
const도 어디에 붙이느냐에 따라 역할이 달라지니 이것도 좀 공부하시는게 좋을거 같고요.
+ 에 const를 리턴하는 건 좀 아닌거 같은데 -_-
대충 Complex의 +를 구현해보자면
class Complex
{
public:
float m_fReal, m_fImaginary;
Complex operator + ( const Complex& rhs )
{
return Complex( m_fReal + rhs.m_fReal, m_fImaginary + rhs.m_fImaginary );
}
}
이런식으로 구현해야 + 가 리턴한 Complex를 계속 다음 연산에 쓸 수 있겠죠?