4장 설계 및 선언

보물창고·2021년 8월 11일
0

이펙티브 c++

목록 보기
5/6

항목 18. 인터페이스 설계

-> 하지만, 사용자가 매개변수의 의미를 확인하지 않고 데이터를 막 넣을 수가 있다. 지금 예제에서 day가 50이 들어가면 안된다.
이때는 wrapper 타입을 만들어서 유저가 만든 사람에 의도에 맞게 사용가능하다.

  • wrapper 타입을 만들자.

    -> main부에서는 wrapper 타입에 맞게 생성자를 호출해야 한다.

-> 추가적으로 wrapper를 확장해 예외처리를 하기도 하지만,
지금 저 상태로도 함수를 사용하는 유저가 Month, Day를 참고해 함수 작성이 가능하다.

항목 19 : 클래스 설계는 타입 설계와 똑같이 취급하자.

  • 값에 의한 전달은 구현하는 것은 복사 생성자를 호출하는 것이다.

항목 20. 값에 의한 전달보다는 상수객체 참조자를 이용하자.

  • const를 통해서 함수 정의부 내에서 값 변경되는 것을 방지하고
  • 레퍼런스를 통해서 복사를 방지하자.

다른 장점이 있다.

  • 함수내의 상향형변환의 효과를 기대할 수 있다.

  • Call by value 일 경우에는 복사에 의해 부모클래스로 형변환이 이루어져서
    파생클래스의 함수값을 기대할 수 없게 된다.

  • Call by Reference의 경우


: 복사가 이루어지지 않고 상향형변환에 의해 원본에 의한 함수가 호출되었다.
-> 그리고 const &타입으로 호출하기 위해서 virtual - 오버라이딩 함수에 const를 추가했다.

21. 함수에서 객체를 반환해야 할 경우에 참조자를 반환하려고 들지말자.

  • 객체의 생성이 어느 곳에서 이루어지는지를 확인하자.

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가 나온다. 왜냐하면

  • operator안의 static 변수는 유일 무이하기 때문이다.
object a, b, c,d;

if((a * b) == (c * d)))
 => ????

-> 마지막 부분 c d 로 호출이 되면
(a
b) 의 result는 (c * d)의 result값으로 바뀐다.
왜냐하면 유일무이한 변수이므로.

항목 22. 데이터 멤버가 선언될 곳은 private

: 변수들은 private에 위치하고, set,get함수로 데이터를 변경하거나, 반환하자. -> 캡슐화

  • public은 외부에 데이터가 노출되므로 캡슐화가 아니다.

  • protected 멤버는 사용 줄이자.
    public이나 도찐 개찐

항목 23. 멤버 함수보다는 비멤버 비프렌드 함수와 가까워지자

: public에 한줄 넣기 싫어서, 즉 캡슐화 아니라고 해서 외부에다가 빼면서까지 해야하는 것인가 생각됨...

항복 24.타입 변환이 모든 매개변수에 적용되어야 한다면 비멤버 함수를 선언하자.

operator 예제



  • -> 정상적으로 컴파일이 된다.

  • 나 : 그런데 이렇게 하면 컴파일이 안됨

1번이 가능한 이유는?
암묵적으로 4를 형변환해서 사용한 것이다.
생성자를 explicit으로 막아보면 어떻게 될까?

-> 불가능한 것을 확인할 수 있다.

알수 있는점.

1) 암묵적으로 실행되는 것을 방지하기 위해서는 생성자에 explicit 키워드를 넣어야 하는 이유이다.
2) 아니면 나)에서도 가능하게 만들고 싶다면 비멤버 변수로 사용하면 해결이 가능하다.

  • 클래스 내부로 올리면 불가능하다.
profile
🔥🔥🔥

0개의 댓글