Scenario: 집에서 Git Remote 올려놓은 Docs파일을 학원에 로컬내에 있는 저장소에서 다운받으려는데 항상 그러던것처럼 생각처럼 잘 되지 않았다. 

그래서 어떻게 하면 할수 있을지 고민하다가 Overwrite 라는 명령어를 통해 해결했다.




Solution:(아래)


1.Local 내 프로젝트를 우클릭후 Synchronize Workspace를 클릭한다.





2.그러면 Rmote repo에 있는 파일 목록이나오는데, 일치하지 않는 파일은 알아서 표시가 뜬다. 그러면 파일을 우클릭후 Overwirte를 누른다

(무분별한 Overwrite는 파일의 손실을 유발할 수 있으니 주의 하자)




3.(로컬 프로젝트 내에 * 표시(Unstage) 가 뜬다 그러면 순서대로 stage 후 commit을 해주자. 






4. 참고로 History(커밋내역)는 Tmea-> Show in history에서 멘트와 누가 했는지 볼수 있다.












Scenario: 이클립스와 디비를 직접 연결하여 DDL 문장을 직접 써줄 수 도있는데, 사실 나중에 MyBatis를 쓰거나 하면 별로 많이 쓰지 않는 기능이고 많이 느리기때문에 자세한 설명은 생략하고 그림으로 대체하겠다.


Solutions(아래)




































Scenario:웹개발 포트폴리오를 만들면서 오픈소스를 참고하다보면 패키지는 엄청많은데 보기가 불편할때가 있다. 
(사실 저렇게 보는걸 의도 한건데 나는 지금까지 모르고 있엇던것 같음)

Solution:(아래)



1.이클립스 Explorer 메뉴바에서 저런식으로 메뉴에 접근한다.





 



이런식으로 보면 훨씬 보기 편해짐




멀티 쓰레드 프로그래밍이 어려운 까닭

보통 멀티 쓰레드 프로그래밍 하면 손사레부터 치는 사람들이 대단히 많다. 이 쪽에 대해 나름 공부를 하고 있다 생각하지만 아직까지 버그가 없으면서 높은 병렬성을 가진, 어느 정도 이상 규모를 가진 프로그램을 일반적인 순차적 프로그래밍을 짜듯 쉽게 만들 자신은 없다. 팀 스위니 같은 천재조차도 멀티 쓰레드 프로그래밍은 쉽지 않다고 고백하는 것을 보면 현재 주된 개발 방식 어딘가에 동시성과 맞지 않는 근본적인 한계가 존재한다는 추측을 하게 된다.

 

멀티 쓰레드 프로그래밍이 어려운 까닭을 파고 들어가면 현재 가장 주류를 이루고 있고 또 성공적으로 적용 중인 구조적 프로그래밍이라는 개념 자체가 동시성 프로그래밍에 적합하지 않다는 점에 그 근본적인 원인이 있음을 알게 된다.1 이러한 원인을 알기 위해서는 우선 구조적 프로그래밍에 대한 이해가 필요하다.

 

구조적 프로그래밍이란 프로그램의 논리를 작은 단위로 나누어 생각할 수 있도록 하위 구조(sub-structure)라는 논리적인 단위를 제공한다. 이러한 하위 구조의 가장 작은 단위는 일반적으로 문장(statement)인데, 구조적 프로그래밍에서는 이들을 순차적으로, 혹은 필요에 따라 비순차적으로 수행하도록 적합한 제어 구조를 제공함으로써 작은 하위 구조로 부터 더 큰 프로그램을 조립해나간다.

 

여기에서 중요한 것은 프로그램의 문맥이 특정한 상태에서 어떤 하위 구조로 진입했을 때, 프로그램 작성자가 그 결과를 결정적으로(deterministic) 예측할 수 있다는 점에 있다. 하위 구조의 동작 결과를 알고 있기 때문에 이러한 하위 구조를 조립한 상위 구조들의 동작 결과도 미리 예측 가능하며, 이러한 전제 하에 상방식(bottom-up), 혹은 하방식(top-down) 설계가 가능해진다. 이 때 각각의 하위 구조가 다른 구조에 영향을 적게 줄 수록 유지 보수가 쉬워지는 경향이 있는데, 이를 위해 그 범위를 가능한 하나의 객체로 좁히기 위한 노력들이 훗날 객체 지향 패러다임에 상당한 영향을 주었다고 한다.

 

이 구조적 프로그래밍에서 가장 강력한 도구를 들라면 역시 서브루틴, 혹은 메쏘드이다. 잘 짜여진 서브루틴이라면 전제 조건(pre-condition)과 사후 조건(post-condition), 부가 효과(side-effect)가 명확하게 정의될 수 있다. 전제 조건이란 서브루틴에 진입하기 이전 프로세스2의 상태가 가져야 하는 전제 조건들을 의미하며, 사후 조건이란 서브루틴을 수행한 이후 반환되는 결과 값 및 변화한 프로세스의 상태이다. 부가 효과란 해당 서브루틴의 수행으로 인해 발생한 프로세스의 변화 자체를 의미한다. 현재의 컴퓨터 모델에서는 서브루틴을 수행하는 사이에 발생한 메모리 영역의 변화 일체가 서브루틴 수행의 부가 효과라고 볼 수 있다.3

 

헌데 기존의 프로그램에 동시성이라는 개념이 등장하는 순간 기존의 이런 도구들이 전부 의미가 없어진다. 두 개 이상의 실행 문맥이 동시에 한 메모리 영역을 읽고 쓰는데에 아무런 제약이 가해지지 않기 때문이다. 헌데 서브루틴이건 하위 구조이건 수행 자체에는 시간이 필요하고, 그 사이에 한 메모리 영역을 두 쓰레드가 동시에 조작하려 시도하면 비결정적(non-deterministic)인 결과, 이른바 데이터 레이스가 나오게 된다.

 

문제는 이 뿐만이 아니다. 설령 데이터 레이스가 존재하지 않는다고 하여도 싱글 쓰레드와 멀티 쓰레드 사이에는 프로그래밍 방식에 있어 현격한 차이가 있다. 만약 단일 쓰레드가 특정 객체를 수정하는 서브루틴를 수행한다 하면 일반적으로 진입 이전과 이후의 객체 상태는 모두 의미 있는 상태일 것이다. 이러한 가정 하에 구조적 프로그래밍이 가능해지는 것이다. 그러나 두 개 이상의 쓰레드가 그러한 서브루틴을 수행한다면 수정이 완전히 이루어지지 않는 불완전한 상태의 객체에 접근하게 될 가능성이 있다. 동시에 접근될 가능성이 있는 모든 객체에 대해 가능한 모든 불완전한 상태에 대한 대비를 해야 한다는 것이다. 이러면 당연히 프로그램의 복잡도가 현격하게 상승하게 되며, 이는 구조적 프로그래밍의 강점 하나가 그대로 사라지는 것을 의미한다.

 

여기에서 구조적 프로그래밍의 가장 큰 전제가 무너지는 것이다. 구조적 프로그래밍에 있어 그 결과를 신뢰할 수 없는 하위 구조는 존재 가치가 없으며, 그러한 하위 구조를 단 하나 가지고 있는 것 만으로도 해당 프로그램은 전혀 신뢰할 수 없는 프로그램이 되고 만다. 그렇지 않은 하위 구조를 짜는 것은 싱글 쓰레드에 비해 몇 배의 노력이 들어가며, 뒤에서도 설명하겠지만 특정 조건을 만족하지 않는 이상 이러한 하위 구조들은 서로 조합이 불가능하다는 치명적인 문제가 존재한다.

 

그간 연구자들이 이에 대해 손을 놓고만 있었던 것은 아니다. 컴퓨터 과학계에서는 수십년 전부터 동시성에 대한 연구가 시작되었고, 특히나 CPU 자원의 공평한 분배가 중요한 운영체제론에서는 동시성에 대한 연구가 광범위하게 진행되어 왔다. 쓰레드나 락, 데이터 레이스 등의 개념을 프로그래밍 자체보다는 운영체제나 시스템 프로그래밍 등의 테마를 공부하며 배우는 사람이 많은 것은 바로 이런 까닭이다.

 

가장 먼저 나온 방안은 (그리고 현재까지 가장 널리 통용되는 방안은) 필요한 경우 락을 이용하여 프로그램 수행을 직렬화하는 것이다. 간단히 말해 의미 없는, 불완전한 상태의 객체에 관한 서브루틴이 수행될 가능성이 있는 경우 진입 지점에 적당히 락을 걸어 두 개 이상의 쓰레드가 동시에 객체를 수정하지 못하도록 막는 것이다. 이 방법은 구현이 쉽고, 가장 기계 친화적인 방식이기 때문에 아직까지 널리 쓰인다.

 

그러나 구조적 프로그래밍과 이 방식이 잘 맞느냐를 묻는다면 회의적이다. 구조적 프로그래밍은 말 그대로 하위 구조의 조합을 통해 프로그램을 만들어가지만, 일반적으로 락 기반 프로그래밍은 객체 단위로 락을 할당한다는 점을 생각해보면 이 방식은 런타임에 존재하는 실제 객체의 상태에도 다분히 의존적이다. 기존에는 주로 하위 구조들이 이루는 프로그램의 구조에 대해서만 신경쓰면 됐다면 4 이제는 여기에 런타임의 프로세스 상태라는 새로운 차원까지 치밀하게 신경써야 한다. 이로 인해 락을 이용한 하위 구조들끼리는 별 다른 조치 없이 그대로 조합하는 것은 불가능하며, 악명 높은 동시성 버그인 데드락이 발생하는 까닭의 99%는 여기에 있다. 5

 

이런 방식 대신, 프로세서가 제공하는 원자적 명령어6를 통해 서브루틴을 수행하는 구간에 대해 해당 객체가 항시 유효한 상태임을 보장하는 방식인 이른 바 Lock-free, Wait-free로 대변되는 non-blocking 동기화 기법도 존재한다. 여기에서는 보통 프로그램의 복잡도를 제어 가능한 수준으로 낮추기 위해 선형화(Linearization)라는 개념을 도입한다. 선형화의 아이디어는 간단히 말해 특정 쓰레드가 특정 객체에 대한 작업를 수행한다 치면 다른 쓰레드에 있어서는 이 작업이 한 순간에 일어난 것처럼 보이도록 하자는 것이다. 데이터베이스의 트랜잭션과 어느 정도 유사한데, 이런 방식으로 접근을 하면 동시적으로 수행되는 각 작업들 사이의 선후 관계를 판별하는게 가능해지고, 또한 락을 이용한 방법과는 달리 하위 구조끼리의 조합도 가능해진다.

 

허나 non-blocking 동기화 기법은 기존의 알고리즘을 선형화시켜야 한다는 제한이 있기 때문에 코딩하기가 대단히 까다롭다. 이는 현대 프로세서들이 제공하는 원자적 연산 명령들의 한계 때문인데, 대부분의 경우 근접해있는 64비트 변수 두 개를 원자적으로 바꾸는 명령 정도가 한계이다. 이러한 명령만을 이용하여 프로그래밍하는 것은 락을 이용한 프로그래밍에 비해 절대 쉽다고 할 수 없다. 그렇기 때문에 대개의 경우는 아주 기초적이고 자주 사용되는 자료구조에 한해 이러한 프로그래밍 기법을 사용하는 것이 대부분이다.

 

그러나 선형화라는 아이디어 자체는 상당히 유용하기 때문에 동시성 모델을 만들고 사고하는데 있어 (락을 이용하는 경우에도) 쓸만하며, 또한 하위 구조간 조합이 아무 제약 없이 가능하다는 강점 덕분에 구조적 프로그래밍과 상당히 궁합이 잘 맞는다. 여기에서 더 나아가 특정 코드 구간에서 일어나는 모든 연산이 원자적으로 일어난다는 것을 보장할 수 있으면 어떨까? 이런 아이디어에서 Transactional memory라는 개념이 등장한다. Transactional memory란 간단히 말해 특정 수행 구간에서 일어난 메모리 변화를 원자적으로 반영시키는 개념으로, 메모리 버젼의 트랜잭션이라고 생각하면 된다. Transactional memory가 구현되면 모든 코드를 아주 쉽게 선형화 할 수 있게 되므로 동기화에 대한 시름거리를 하나 덜어버리는 셈이 되나, 안타깝게도 아직까지는 이를 실용적인 수준까지 구현한 사례는 존재하지 않는다.

 

현재까지는 어느 쪽이든 그 난이도가 낮지 않다. 이 외에도 수많은 방법들이 제안되었고 또 제안되고 있지만, 아직까지는 확실하게 은탄환이라 불릴 만한 해법은 나오지 않은 상태이다. 병렬, 동시성 프로그래밍은 로직 자체를 고민하는 것도 만만치 않은데 여기에 이런 다양한 문제들이 엮이면서 그 난이도가 살인적인 수준까지 올라간다. 마땅한 방법이 없는 현재로써는 이를 하나 하나 공부하며 그때 그때 맞는 방법론을 찾아 적용하는 수 밖에 없어 보인다.

 

 

 

출저 : http://summerlight-textcube.blogspot.kr/2010/04/%EB%A9%80%ED%8B%B0-%EC%93%B0%EB%A0%88%EB%93%9C-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%EC%9D%B4-%EC%96%B4%EB%A0%A4%EC%9A%B4-%EA%B9%8C%EB%8B%AD.html

  1. 물론 이게 goto를 쓴다고 해결된다는 의미는 절대 아니다. [본문으로]
  2. 여기에서 프로세스란 시스템 프로그래밍적 관점에서의 그 용어가 아닌, 프로그램의 인스턴스로써의 프로세스를 의미한다. [본문으로]
  3. 물론 이에 한정되지는 않는다. I/O도 부가 효과라고 볼 수 있으니까. [본문으로]
  4. 꼭 그렇지만은 않지만, 대부분은 좋은 설계에 의해 해결된다. [본문으로]
  5. 이 뿐만 아니라 lock contention, lock convoying등 락으로 인한 문제점은 셀 수도 없이 많다. [본문으로]
  6. Compare and swap등. [본문으로]

[펌글]

디바이드앤퀀쿼, 다이나믹, 그리디 세 가지 방법만알아도 문제가 쉽게 풀린다.


어디선가 봤는데 알고리즘은 저 3가지 위주로만 공부하라고 했는데,, 옼키 였나

kdlp 였나


Scenario:강의들을 동안은 권한주기 및 계정생성은 한번 밖에 안해봐서, 

어느날 새로운 계정으로 들어가 테이블들을 따로 관리하려니까 SQLDEVELOPER ID가 유효하지 않다고 하더라.


이유를 생각해보니 계정 생성및 grant 도 안해줘서 그런거였다. 이런 건 그냥 스크랩 해 두는 게 좋겠다.


solution:


Bash 0.96 KB
  1. Administrator@WIN-UB18TI2GOTU MINGW64 /
  2. $ sqlplus system/oracle
  3.  
  4. SQL*Plus: Release 11.2.0.2.0 Production on ±Ý 1¿ù 6 11:35:51 2017
  5.  
  6. Copyright (c) 19822014, Oracle.  All rights reserved.
  7.  
  8.  
  9. Connected to:
  10. Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production
  11.  
  12. SQL> create user itcenter identified by java;
  13.  
  14. User created.
  15.  
  16. SQL> grant connect, resource to itcenter;
  17.  
  18. Grant succeeded.
  19.  
  20. SQL> exit
  21. Disconnected from Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production
  22.  
  23.  
  24.  
  25.  
  26. /////////추가로 필요 명령어들/////////////
  27. SQL> SHOW USER;
  28. SQL>SELECT * FROM all_users;
  29. //다른 계정으로 넘어가기
  30. SQL>conn testuser/testuser;
  31. //유저 비밀번호생성
  32. SQL>ALTER USER testuser IDENTIFIED BY "chagepwd";
  33. //유저 삭제
  34. SQL>DROP USER testuser;
  35.  
  36. //유저명 변경은 어렵다고하니 다음에 알아보도록 하자 -_-;;
  37.  
  38. //유저 비밀번호 변경
  39. SQL>alter user scott identified by scott;


사수가 없어서 혼자 한다는 신입분들 글이나 진로문제 글들을 읽다보니 

 

저 신입때 만났던 사수분이 생각나네요. 그때는 진짜 힘들었지만 신입분들이 스스로 공부할 때 

 

참고하면 좋겠다 싶어서 써봅니다. 입사 첫주에 다짜고짜 스트럿츠로 로그인되는 게시판 만들어 학원에서 배운거라 여차저차 만들었더니 

 

둘째 주에 스프링 대충 교육시켜주고 디비테이블 긁어서 리스트로 뿌려주는 스프링소스 던져주고 스프링 으로 바꿔

 

바꾸고 나니 셋째 주에는 AJAX이용해서 DB에서 가져와서 동적으로 변하는 셀렉트박스 대분류,중분류,소분류 만들어.

 

넷째주에는 제이쿼리로 바꾸고 데이터 형식도 JSON으로 바꿔. 5주차되니까 마이플랫폼 가져와서 교육자료 던저주고는 

 

리스트 2개뿌리고 각 리스트 데이터끼리 교환가능하해.

 

사실 마이플랫폼은 그때 이후로는 쓸일이 없었다는 슬픈전설이..

 

마이플랫폼은 왜했냐니까. 그런것도 써봐야 어떤 UI를 만나도  쫄지 않는다고.. 그렇게 6주차째 되니까 너는 이제 어떤 서버프레임워크와 어떤 UI를 만나도 데이터를 자유롭게 주고받을 수 있다며 DB를 하자고 함. 


6주차에 조인 아우터 조인 서브쿼리 열데이터 행으로 출력 행데이터 열로 출력 기본 함수들 트리형으로 보여주기 아무튼 DB데이터가 화면에 어떤식으로 나타날수 있는지는 이때 다해본거같음. 


사수가 이렇게 보이게 해봐 하면 나는 쿼리 만들 어서 컨펌받는 식으로 했음. 이때가 정말 야근도 많이하고 제일 힘들 었음 


7주차부터는 저장 프로시져함 이 부분은 프로그래밍 기초를 배우는 느낌이라 별로 어렵지 않았음.


8주차에는 실행계획 보기 옵티마이져.인덱스설정 이런 튜닝쪽 비슷하게 배움. 힌트나 인덱스에 따라 빨라지고 느려지는거 보여주면서 그렇게 두달하니까. 


이제야 넌 실무를 할 수 있다고 하길래 끝난줄 알았더니 그냥 개발을 할줄 아는것과 이해하는 것은 다르다고..

 

주는 책을 읽어서 ppt로 정리하라고 함(이후 회사 교육자료가 됨.) 진짜 고역이었음. 책도 디자인패턴, 대용량데이터베이스 솔루션같은

 

그 당시 나로서는 진짜 머리깨지게 어려운 책들. 디자인패턴은 자바 를 좀 더 이해할 수 있었다는거 말고 딱히 쓸일없었지만 대용량데이터 베이스솔루션(이화식 저.)은 지금도 도움이 많이됨. 

 

신입들에게 추천함. DB가 물리적으로 어떻게 돌아가는지 이해할 수 있는게 아주 좋음. 


결합인덱스나 테이블 데이터들을 혹은 코드를 어떻게 전략적으로 가져가야 될지 이해하게 되었음.

 

사실 저는 아직도 책의 50%도 이해한거 같지는 않지만. 그정도로도 도움됨.

 

그 밖에도 별 이상한 책들도 많이 정리함. 자바랑 상관없는거. 컴구조쪽에서 괜찮았 던건 인사이드머신? 


맞나 기억이 가물해서 다른 컴구조 책에 비해서 쉽게 설명해주는게 좋았음. 

 

그리고 네트워크 쪽은 후니의 쉽게 쓴 시스코 네트워킹. 네트워크 지식이 별 필요없는 것 같지만 실무에서 은근히 도움될 때 많음. 

 

특히 IP같은 프로토콜에 대한 이해가..

 

자료구조 알고리즘 쪽에서는 '뇌를 자극하는 알고리즘' 이것도 알고리즘 책치고 이해도 잘되고 아주 쉽게 읽힘. 


이걸로 맛보고 알고리즘 전공서적을 보면 좋을 듯. 

 

"IT 이것도 모르면 하지 마라"라는 책도 읽어보면 좋아요.

 

그리고 이 책은 개발하는 데는 그닥 도움되지는 않지만 

 

제가 사수에게 입사 선물로 받은 책이고 내리갚음으로..또 신입들어오면 제가 선물로 주는 책인데요. 

 

신입분들은 읽어보면 좋아요. 

--------------------------------------

감명깊게 읽은 글이라 스크랩해두었습니다.


Scenario:학부시절 학생관리 프로그램을 만드는데 입력받는데 중간중간에 입력을 안받고 넘기는 경우가 생김


Solution:(아래)


간혹 


Scanner scan = new Scanner(System.in);

int i = scan.nextInt();        //1번코드

String s = scan.nextLine();  // 2 코드


이런 코드를 짤 때 첫번째 int 만 입력을 받고 그다음 nextLine() 부분을 Skip 하는 경우가 발생한다.


이는 nextInt() 에서 Enter 를 칠 때 발생하는 '개행문자'를 처리하지 않고 버퍼에 남기기 때문이다.


따라서 scanner 에 있는 개행문자 \r\n 을 비워주어야 하지만,


자바에는 Scanner 에는 flush 함수가 없다고 한다.


그렇다고 방법이 없는 것은 아닌데, 별로 맘에 들지 않는 임시방편으로 몇 가지가 있다.



1. 1번과 2번 코드 사이에 scan.nextLine() 을 집어넣어서 개행문자를 처리.


2. 1번과 2번 코드 사이에 scan.skip("[\\r\\n]+");  집어넣으면 개행문자 스킵


3. Scanner 객체를 입력받을때마다 만든다.. 

 

    Scanner scan1 = new Scanner(System.in);  

    Scanner scan2 = new Scanner(System.in);

    (자원의 낭비가 커서 비추)   

const란 const로 정의된 변수를 상수화하여, 그 값을 변경하지 못하게 하는 것이다.

변경하지 않아야 하는 변수를 수정하여, 난 에러는 찾기가 매우 힘들다. 이러한 변수사용시 그값이 변경되지 않아야 하는 곳에 사용하여, 그러한 에러를 컴파일시 확인이 가능하게 하게 한다.

 

#변수의 상수화

const [변수 타입] [변수명] =  초기화 값 ;  //선언시 초기화 값을 넣어야 된다. 초기화 값을 넣은 후 변경을 할 수 없다.

ex>

const int A = 12345;  //A를 상수화하여 12345값으로 상수화(고정)된다.

const float B = 123.45;  //B를 상수화하여 123.45값으로 상수화(고정)된다.

 

const [변수 타입] * [변수명];  //변수명이 가리키는 주소의 값을 변경할 수 없다.

ex>

const int * pA;

int a = 3;

pA = &a;   //pA에 a의 주소값을 넣는다.

*pA = 10;  //컴파일 에러 : pA가 가리키는 주소의 값이 상수화 되어 변경할 수 없다.

 

[변수 타입] * const [변수명] = 초기화 값;  //변수명이 가리키는 주소를 변경할 수 없다.

ex>

int a;

int * const pA = &a;

pA = &a;   //컴파일 에러 : pA가 가리키는 주소가 상수화되어 변경할 수 없다.

*pA = 10;  //pA가 가리키는 주소의 값을 변경한다.

 

const [변수 타입] * const [변수명] = 초기화 값;  //변수명이 가리키는 주소와 그주소의 값도 변경할 수 없다.

ex>

int a;

const int * const pA = &a;

pA = &a;   //컴파일 에러 : pA가 가리키는 주소가 상수화되어 변경할 수 없다.

*pA = 10;  //컴파일 에러 : pA가 가리키는 주소의 값이 상수화 되어 변경할 수 없다.

a = 3;  //이렇게 직접 값을 변경하는 수 밖에 없다.

 

#멤버함수의 상수화

[리턴타입] [함수명] (매개변수) const {함수내용...};  //해당 함수안에서는 클래스의 모든 멤버 변수는 상수화되어 값을 변경할 수 없고, 포인터 반환이 되지 않는다. 또한 멤버함수의 경우 같이 상수화된 함수만을 사용할 수 있다.

ex>

int a;  //멤버 변수

void FunctionA(Test * pTest) const;  //상수화된 멤버 함수

void FunctionB(int b) { b = 1; };  //일반 맴버 함수

void FunctionC(int c) const { c = 1; };  //상수화된 멤버 함수

 

void Test::FunctionA(Test * pTest) const

{

  int b = 1;  //내부에 선언한 변수의 값을 변경 할 수 있다.

  a = 1;  //컴파일 에러 : 멤버변수 값을 변경 할 수 없다.

  pTest->a = 1;  //클래스 포인터를 사용하여 멤버 변수의 값을 변경 할 수 있다. 그러나 이것은 바람직하지 않은 사용이다. 이렇게 사용할 바에는 그냥 일반함수로 만들어 사용하는 게 낮다.

  FunctionB(2);  //컴파일 에러 : 상수화가 안된 맴버함수를 사용할 수 없다.

  FunctionC(2);  //상수화된 멤버함수로 컴파일된다.

}

 

#const와 함수 오버로딩

const 사용에 따라 동일한 함수명과 동일한 매개변수를 가지고 있다하여도 함수오버로딩이 가능하다.

ex>

void FunctionA(void);  //일반 함수

void FunctionA(void) const;  //const를 사용한 함수오버로딩된 상수 함수

 

void FunctionB(void)

{

  FunctionA();  //일반 함수가 실행된다. 상수함수도 실행할 수 있지만 우선순위가 일반함수가 더 높다.

}

void FunctionC(void) const

{

  FunctionA();  //상수 함수가 실행된다. 오직 상수함수만을 실행 할 수 있다.

}



#include <iostream>

#include <list>

using namespace std;


bool Predicate(int n){

    return n >= 30;

}


int main(){


    list<int> lt;


    lt.push_back(10);

    lt.push_back(20);

    lt.push_back(30);

    lt.push_back(40);

    lt.push_back(50);


    list<int>::iterator iter;

    for (iter = lt.begin(); iter != lt.end(); ++iter){

        cout << *iter << ' ';

    }

    cout << endl;


    iter = lt.begin();

    iter++;

    iter++;


    // erase 삭제

    list<int>::iterator iter2 = lt.erase(iter);

    for (iter = lt.begin(); iter != lt.end(); ++iter){

        cout << *iter << ' ';

    }

    cout << endl;

    cout << "iter2 : " << *iter2 << endl;


    lt.push_back(10);

    lt.push_back(10);


    for (iter = lt.begin(); iter != lt.end(); ++iter){

        cout << *iter << ' ';

    }

    cout << endl;


    // 리스트에서 원소 10 제거

    lt.remove(10);


    for (iter = lt.begin(); iter != lt.end(); ++iter){

        cout << *iter << ' ';

    }

    cout << endl;



    // Predicate 함수에 해당하는 원소 제거 (30보다 크다)

    lt.remove_if(Predicate);


    for (iter = lt.begin(); iter != lt.end(); ++iter){

        cout << *iter << ' ';

    }

    cout << endl;


    return 0;

}

+ Recent posts