-> 하지만, 사용자가 매개변수의 의미를 확인하지 않고 데이터를 막 넣을 수가 있다. 지금 예제에서 day가 50이 들어가면 안된다.
이때는 wrapper 타입을 만들어서 유저가 만든 사람에 의도에 맞게 사용가능하다.
-> 추가적으로 wrapper를 확장해 예외처리를 하기도 하지만,
지금 저 상태로도 함수를 사용하는 유저가 Month, Day를 참고해 함수 작성이 가능하다.
함수내의 상향형변환의 효과를 기대할 수 있다.
Call by value 일 경우에는 복사에 의해 부모클래스로 형변환이 이루어져서
파생클래스의 함수값을 기대할 수 없게 된다.
: 복사가 이루어지지 않고 상향형변환에 의해 원본에 의한 함수가 호출되었다.
-> 그리고 const &타입으로 호출하기 위해서 virtual - 오버라이딩 함수에 const를 추가했다.
1) 함수 내의 스코프에서 이루어진다면 이것은 지역변수이다.
지역변수는 스코프를 벗어나면 해제를 하게 되는데 해제되는 메모리를 참조형식으로 반환한다? 이것은 이미 사라진 메모리를 반환하는 것이므로 문제를 발생시킨다.
-> 출력창에도 warning 메시지 나타났다.
결과적으로는 이상없지만, 해서는 안되는 동작이다.
2) 힙공간에 할당 후에 참조형식으로 반환하면 어떨까?
어쨋든 스코프 내에서 만들어지는데,,,
-> 지역변수로 만들든, 힙으로 생성하든 어쨋든 반환객체에 대한 생성자-소멸자 호출은 어쩔 수 없는 일이다.
#include <iostream>
#include <string>
#include <vector>
class object
{
private :
int a;
public :
object(const int& inData)
: a{inData}{}
object& operator *(const object& other)
{
object result = this->a * other.a;
return result;
}
};
int main()
{
object a(3);
object b(2);
object c = a * b;
return 0;
}
3) static으로 만들면 괜찮지 않을까?
놉!!!
호출하려는 함수 내부에 static변수가 존재할 경우, 유일 무이한 값이다.
예를 들어 이런 함수가 있고,
object& operator *(const object& other)
{
static object result = this->a * other.a;
return result;
}
이러한 조건이 있다면 무조건 true가 나온다. 왜냐하면
object a, b, c,d;
if((a * b) == (c * d)))
=> ????
-> 마지막 부분 c d 로 호출이 되면
(a b) 의 result는 (c * d)의 result값으로 바뀐다.
왜냐하면 유일무이한 변수이므로.
: 변수들은 private에 위치하고, set,get함수로 데이터를 변경하거나, 반환하자. -> 캡슐화
public은 외부에 데이터가 노출되므로 캡슐화가 아니다.
protected 멤버는 사용 줄이자.
public이나 도찐 개찐
: public에 한줄 넣기 싫어서, 즉 캡슐화 아니라고 해서 외부에다가 빼면서까지 해야하는 것인가 생각됨...
가
-> 정상적으로 컴파일이 된다.
나 : 그런데 이렇게 하면 컴파일이 안됨
1번이 가능한 이유는?
암묵적으로 4를 형변환해서 사용한 것이다.
생성자를 explicit으로 막아보면 어떻게 될까?
-> 불가능한 것을 확인할 수 있다.
1) 암묵적으로 실행되는 것을 방지하기 위해서는 생성자에 explicit 키워드를 넣어야 하는 이유이다.
2) 아니면 나)에서도 가능하게 만들고 싶다면 비멤버 변수로 사용하면 해결이 가능하다.
- 클래스 내부로 올리면 불가능하다.