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


웹브라우저를 나타내는 클래스가 있다.

이 클래스에는 캐시를 비우는 함수, URL 기록을

없애는 함수, 쿠키를 제거하는 함수가 있다.


이 세 동작을 한꺼번에 하고 싶은 사용자를 위해

세 함수를 불러주는 함수도 준비해 둘 수 있을 것이다.




class Web{

private:

...

public:

...

void clearEverything();

}


위와 같이 멤버함수로 제공해도 되지만,

비멤버 함수로 제공해도 된다.


void clearWeb(Web& wb){

wb.fct1();

wb.fct2();

...

}


멤버 버전인 경우 Web 클래스의 private 멤버에

접근할 수 있다. 따라서 캡슐화의 정도가 낮아진다.

반면 비멤버 비프렌드 함수일 경우 Web클래스의

어떠한 private 멤버에 접근할 수 없다.

또한 패키징 유연성과 확장성을 높히는 동시에

컴파일 의존도도 낮출 수 있다.




주의해야 할 점은 함수는 어떤 클래스의 

비멤버가 되어야 한다는 말이 그 함수는

다른 클래스의 멤버가 될 수 없다라는 의미가

아니라는 것이다. 위의 clearWeb라는 함수는

다른 클래스의 정적 멤버함수로 만들어도 된다.

(Web클래스의 멤버만 아니면 됨)




더 나아간 방법 --> 같은 네임스페이스 안에 두는 것


namespace WebStuff {

class Web { ... };

void clearWeb(Web& wb);

...

}


네임스페이스는 클래스와 달리 여러 개의

소스 파일에 나뉘어 흩어질 수 있다.

clearWeb같은 함수는 편의상 준비한 함수들

이기 때문에, 이 함수가 없다해도 사용자는

각각의 함수들을 따로 호출하면 된다.




편의 함수가 많이 생길 수 있는 클래스라면

연관이 있는 편의 함수를 하나의 헤더 파일에

몰아서 선언하고, 같은 네임스페이스에 넣어주자.


//"web.h"

namespace WebStuff {

class Web { ... };

...

}


//"bookmark.h"

namespace WebStuff {

...

}


//"cookies.h"

namespacce WebStuff {

...

}


이렇게 하면 필요한 기능에 대해서만

include해서 사용하면 되기 때문에

필요없는 기능들에 대한 컴파일 의존도를

낮출 수 있다. 클래스의 멤버함수일 경우

이런 식으로 기능을 쪼개는 것 자체가 불가능하다.

하나의 클래스는 그 전체가 통으로 정의되야 하고

여러 조각으로 나눌 수가 없기 때문이다.




편의 함수 전체를 여러 개의 헤더 파일에

나누어 놓으면 확장도 손쉬워진다.

해당 네임스페이스에 비멤버 비프렌드 함수를

원하는 만큼 추가해주면 끝난다.




POINT!!

멤버 함수보다는 비멤버 비프렌드 함수를 자주 쓰도록하자.

캡슐화 정도가 높아지고, 패키징 유연성도 커지며, 기능적인 확장성도 늘어난다.

백트래킹 알고리즘 N Queen (정올)


이 문제를 푸는데 10시간은 걸린 듯하다.

어떤 식으로 풀어야 한다는 것은 머리에 그려졌지만

대각선 방향으로의 체크를 어떤 식으로 진행해야 할지

방법이 떠오르지 않았다. 내가 수학문제를 푸는지

프로그래밍을 하고 있는지 모르겠다. 맘에 안든다.






01. 문제 개요



02. 선언



03. 체크 방법




04. 답 찾기



06. 메인



제발 이런 문제는 테스트에 나오지 않길..


데이터 멤버가 선언될 곳은 private 영역임을 명심하자.




1. 문법적 일관성

데이터 멤버가 public이 아니라면 접근은

함수로 해야할 것이고, 공개 인터페이스에 있는 것들이

전부 함수뿐이라면, 그 클래스에 멤버에 접근하고 싶을 때

괄호를 붙여야 하는지 말아야 하는지 고민할 필요가 없다.




2. 데이터 멤버의 접근성에 대해 훨씬 정교한 제어를 할 수 있다.

멤버 함수를 통한 접근은 접근 불가, 읽기 전용, 읽기 쓰기 접근을

내가 직접 구현할 수 있다. 심지어는 쓰기 전용 접근까지도




3. 캡슐화

자동차가 지나가는 속도를 모니터링 하는 클래스가 있다.

class speedData{

...

public:

void Add(int speed);

double average() const;

...

}


평균 값을 구하는 average 함수를 구현하는 방법은 두 가지이다.

첫 번째, 평균값을 넣어두는 데이터 멤버를 반환하는 방법

두 번째, 함수가 호출될 때 마다 평균값을 계산해서 반환하는 방법

이렇듯 평균값 접근에 멤버 함수를 통해 하게되면

(평균값을 캡슐화 하게되면) 내부 구현을 이렇게 혹은 저렇게

바꿀 수 있게 되고, 사용자는 기껏 해봤자 컴파일만 다시하면 된다.




4. 구현상의 융통성을 전부 누릴 수 있다.

데이터 멤버를 읽거나 쓸 때 다른 객체에 알림을

보낸다든지, 클래스의 불변속성 및 사전조건, 사후조건을

검증한다든지, 스레딩 환경에서 동기화를 건다든지 하는 일이다.

(C# 에서는 프로퍼티라 한다.)




5. 불변속성

사용자로부터 데이터 멤버를 숨기면, 클래스의 불변속성을

항상 유지하는 데 절대로 소홀해질 수 없게 된다. 불변속성을

보여줄 수 있는 통로가 멤버 함수밖에 없기 때문이다.


캡슐화는 현재의 구현을 나중에 바꿀 수 있다. --> 3번 참고

데이터 멤버가 public으로 되어있다면 캡슐화되지 않았다는 뜻이고

현재의 구현을 나중에 바꾸게 되면 코드가 깨지게 된다.


public으로 데이터 멤버를 선언할 경우 이 데이터 멤버를

변경하고자 할 때, 이 데이터를 쓰고 있는 모든 부분을

수정해야 할 것이며, protected 데이터 멤버라고 해도

상속받는 모든 클래스의 코드가 깨지게 될 것이다.




POINT!!

1. 데이터 멤버는 private로 선언하자,

2. 접근 수준은 private(캡슐화 제공) 그리고 나머지 (캡슐화 없음)으로 구분하자.

+ Recent posts