프로그래밍/C2012. 8. 21. 18:51

출처: http://kldp.org/node/71304

typedef struct aa = {
    int a;
    int b;
}AA;
 
/* 1번 방법 */
AA a = {
    1,
    2
};
 
/* 2번 방법 */
AA b = {
    .a = 1,
    .b = 2
};
 
/* 3번 방법 */
AA c = {
    a:1,
    b:2
};

1은 ANSI 표준, 2는 ISO C (C99) 표준, 3은 GCC 확장 기능입니다.

'프로그래밍 > C' 카테고리의 다른 글

인라인 어셈블리  (0) 2012.09.25
include guard에 대해서  (0) 2012.09.24
error: expected identifier before numeric constant  (0) 2012.07.03
정적 라이브러리, 동적 라이브러리 만들기  (0) 2012.04.04
sprintf 사용법  (0) 2012.04.03
Posted by code cat
프로그래밍/JAVA2012. 8. 6. 10:41

https://developers.google.com/java-dev-tools/download-wbpro 에서 알려준 링크


Eclipse 3.7 (Indigo)


http://dl.google.com/eclipse/inst/d2wbpro/latest/3.7


를 사용하면 다음과 같이 인스톨이 제대로 되지 않는다.  


Cannot complete the install because one or more required items could not be found.



이는 WindowBuilder Pro에서 필요한 컴포넌트들이 WindowBuilder Pro 사이트에 존재하지 않아서 이다.


대신, eclipse Indigo 사이트에서 다운을 받아보자.



indigo관련 릴리즈들이 많아서 처음에 오래 걸린다.


리스트가 뜨면, Filter에 WindowBuilder 와 SWT 와 Swing 등으로 필터를 걸고 찾아서 인스톨 하면 된다.



'프로그래밍 > JAVA' 카테고리의 다른 글

OTA Package Utility  (0) 2013.11.25
Swing desiginer LookAndFeel 종류  (0) 2013.11.19
Java Generics  (0) 2012.10.01
ant 빌드가 안될 때  (0) 2011.10.19
Posted by code cat
프로그래밍/C2012. 7. 3. 17:19

error: expected identifier before numeric constant


위와 같은 에러가 나는 이유

1. include로 헤더파일을 추가했는데 어디선가 같은 이름의 매크로가 꼬였을 때,

해결책 --> (에러 나는 라인의 매크로로 grep을 잡아보자!)


'프로그래밍 > C' 카테고리의 다른 글

include guard에 대해서  (0) 2012.09.24
구조체 초기화 방법  (0) 2012.08.21
정적 라이브러리, 동적 라이브러리 만들기  (0) 2012.04.04
sprintf 사용법  (0) 2012.04.03
sscanf 사용법  (0) 2012.03.28
Posted by code cat
프로그래밍/C++2012. 4. 28. 23:26

 

하기내용에서 사용된 코드는  Android Framework  분석을 위한 c++ 에서 사용된 코드임을 밝힙니다.

1. cout, endl의 원리

cout은 원래 객체이며, endl의 경우 함수이다. 아래는 cout과 endl를 구현해 본 소스코드이다.

추가로 tab이나 two_endl의 사용자정의 함수도 추가했다.

그럼 이게 기존거랑 충돌이 나느냐? 아래를 보자.

위와 같이 우리가 만든 함수들도 기존 std 네임스페이스와 같이 쓸 수 있다.

cout은 c와 달리 출력 형태가 무엇인지 정해주지 않아도 된다. 그렇다면 사용자 정의 객체 일 경우 어떻게 해야 할까?

아래는 사용자 정의 객체인 Point를 만든 코드이다.

cout << p; 이 부분은 결국 cout.operator<<(Point)가 있으면 된다.

'프로그래밍 > C++' 카테고리의 다른 글

C++에서 C 함수 사용하기  (0) 2013.02.02
생성자 뒤에 : 붙는 경우  (0) 2013.01.01
Android Framework 분석을 위한 C++ 4일차  (0) 2012.04.26
[C++] Smart Pointer  (0) 2012.04.25
Android Framework 분석을 위한 C++ 3일차  (0) 2012.04.25
Posted by code cat
프로그래밍2012. 4. 27. 12:08

출처: kldp

 

페어 코딩에 대한 좋은 글이 있어서  kldp에서 퍼왔다.

 

페어코딩을 하기 위한 자세 (원제는 아니였는데 그냥 제목을 붙여봤다)

 

* 소스코드의 소유와 책임이 개인이 아닌 팀에 있다. 아무나 다른 사람의 코드를 비판하고 고칠 수 있다.
* "우리"에 잘못이 있지, 특정인에게 잘못이 있지 않다. 코드는 비난하더라도 사람은 비난하지 않는다.
* 같이 일하다 결과가 있을 때마다 서로 축하한다. 하이 파이브나 괴성 등으로 서로의 감정을 공유한다.
* 급한 일이 있으면 상대에게 이야기하고 양해를 구한다. 서로 존중하면서 해결해야 할 사적인 문제는 바로 해결한다.
* 아무리 나보다 못한 사람에게도 배울점이 있음을 간과하지 말며, 나도 언제나 다른 사람이 저지르는 실수를 똑같이 저지를 수 있음을 잊지 않는다.
* 좋은 아이디어가 있으면 바로 바로 상대방과 상의하며 프로그래밍 한다.
* 짝이 틀린 것을 지적하면 고마움을 표한다.
* 짝이 틀린 길로 들어서면 바로 지적한다. 만일 그에 대해 짝이 멈추지 않게 계속 한다면 의중을 파악하려고 노력한 후 그래도 자신이 옳다는 생각이 들면 기회를 기다렸다가 조리있게 왜 그것이 틀렸는지 설명한다.
* 일이 안풀리고 막히면 바로 상대에게 넘긴다.
* 상대에게 프로그래밍을 해설 및 중계방송 하는 느낌으로 자신의 생각을 끊임없이 말해준다. 상대가 자신의 생각을 이야기 하면 귀담아 듣고 문제는 없는지 어떻게 앞으로 일들이 펼쳐져야 할지 머리속에 그리며 함께 일한다.
* 일을 마치기 전에 상대에게 얼마나 고마운지, 짝이 없었다면 자신이 얼마나 형편없는 결과물을 만들어 냈을지 서로 이야기 하고 격려한다.
* 열심히 일한 후에는 칼퇴근 한다.

Posted by code cat
프로그래밍/C++2012. 4. 26. 10:49

1. 순수 가상함수와 추상 클래스

 

추상클래스를 만들기 위해서는 가상함수를 선언해야 하며, 0으로 초기화 시켜주어야 한다.

추상클래스의 목적은 이를 상속하는 하위 클래스에게 구현의 임무를 부여하는 데 있다.

 

인터페이스의 탄생

 

좀 더 이쁘게 할려면, 이렇게 바꾸자.

 

인터페이스는 기능별로 나누는게 좋고, 다중상속으로 처리하면 된다.

 

 

 

 

다음은 메뉴만들기를 객체 지향적으로 구현해 본 것이다.

 

메뉴를 만든다면, 우선 여러가지 형태가 있겠지만,

추상메뉴

 |-  팝업 메뉴     Vector<"추상메뉴">

  `-  메뉴 아이템

 

팝업메뉴는 여러가지 메뉴가 있을테니, Vector<"추상메뉴">로 구현하면 되고,

모든 메뉴는 title 및 command가 있으니, 이는 추상메뉴에 구현한다.

 

이렇게 하위 객체를 부모로 싸잡아서 구현하는 걸 composite 패턴이라고 한다. 

 

밑은 composite 패턴으로 구현한 고객관리 메뉴 코드이다.  동작성은 없다.

 

 

자원 반납을 위해서, 소멸자를 추가하자.

 

 

 

가상 소멸자

이렇게 해서 자원을 해지하려면, B가 해지되는게 아니라, A가 해지된다.  이를 해결하기 위해선,

~A() {cout << "메모리A해지" <<endl;}

앞에 virtual을 붙여서

 virtual ~A() {cout << "메모리A해지" <<endl;}
이라고 정의하면 된다. 

 

근데 또 가상소멸자에 의한 가상테이블이 생기는 것을 없애려, protected로 선언해, 컴파일 시 에러가 나게 하는 방법도 있다.

소멸자는 delete static_cast<B*>(p);로 바꿔야 한다.

 

그러나 delete static_ca.. 아 쓰기도 어려운데, 그래서 할 수 있는 방법이 다음과 같다.

.... 걍 c++ 하지 말자.

 

정리하자면, 상속관계에 있는 클래스에서 부모 클래스이 소멸자는 항상 가상함수로 만들자.

 

갑자기 생각난  mix-in 하고 upcasting하고 어떻게 틀리더라...

 

 

가상함수를 쓰면 다음과 같은 결과를 얻는다.

주석에도 있듯이,

foo가 가상이 아니라면 : static binding => p의 포인터타입으로 결정
                                 A::foo()호출
foo가 가상이라면        : *p[1]() 라고 기계어 코드를 생성해 놓는다.

 

*p[1]은 실제로 가상함수테이블(Virtual Function Table)의 인덱스를 가리킨다.  보통 컴파일러는 가상함수의 기능을 구현하기 위해 가상함수 테이블과 가상함수 테이블 포인터를 사용하는데, 가상함수테이블은 가상함수의 모든 주소를 가지고 있는 배열이며, 가상함수 포인터는 이 테이블을 가리킨다.

 

즉 가상함수를 사용하면, 다형성을을 얻을 수 있으나,

 

1. 가상함수 테이블을 위한 메모리 할당,

2. 가상함수 테이블 포인터로 인한 객체의 크기 증가,

3. 함수 호출시 함수 포인터에 의한 호출로 오버헤드 증가,

4. Inline을 사용하지 못함

 

다는 단점도 있다.  그리고 한가지 더! 가상함수는 run-time에 호출 될 함수가 결정되지만, default paramemter는 compile-time에 결정된다.  따라서 예상치 못한 결과가 나올 수 있으니 주의하자.

 


composite 패턴 실습

 

다음은 composite 패턴을 이용해서 만들어 본 비디오 대여점 메뉴이다. 기본적인 메뉴만 구성되어 있다.

 

 

 

 

Observer 패턴 실습

위에서 생성된 메뉴의 메세지를 처리하기 위한 모든 객체는 인터페이스를 정하고, 그 인터페이스로부터 상속받은 형태로 구현 할 수 있다.

관찰자(Observer)패턴은 하나의 상태 변화를 여러 객체에게 알려주는 패턴이다.

 

 

 

객체의 이벤트 처리를 위해 인터페이스 방식(바로 전 예제)이 아닌 함수와 연결 하는 방식도 있다.

다음을 보자.

 

 

 

다중상속

 

다중상속에는 여러가지 문제점 있겠지만, 아래와 같이 (주석처리 된 부분) 다중상속시에 발생할 수 있는 문제점이 있다.

 

주석같이 상속 받으면,

 

                  RefBase

                 /           \         

        IInterface         BpRefBase

                 \            /

                  HelloWord

 

IInterface, BpRefBase 모두 mCount라는 변수를 상속 받았으니, 컴파일러는 어느 녀석을 써야 하는지 모른다.  그래서 대신, virtual 키워드를 써서 처리해야 한다.  아니 이런 구조를 아예 피하자.

 

 

 

다중상속과 캐스팅

 

reinterpret_cast<B*>(&c)는 c를 어떻게든 B처럼 보이게하라고 캐스팅 한다. 즉 C안에서 B의 위치를 찾는게 아니라, C가 B처럼 되는 것이다. 그래서 만약 우리가

 

한편 x와 y가 public으로 바뀌서, y에 값(10)을 대입해 보면 y가 아닌 x가 10으로 대입되는 걸 볼 수있다. (x가 먼저 상속받기 때문에, 그 주소에는 x가 먼저 위치하고, 그 다음에 y가 위치한다.)

 

 

 

 

RTTI (Run-Time Type Informationi)

런타임에 typeinfo를 가져온다.  typeinfo는 가상함수테이블 상위에 위치하고 있으며, 가상함수가 있을 때만 존재한다.

 

 

 

 

 

 

 

 

 

템플릿

 

템플릿과 타입

 

 


 

'프로그래밍 > C++' 카테고리의 다른 글

생성자 뒤에 : 붙는 경우  (0) 2013.01.01
cout , endl 의 원리  (0) 2012.04.28
[C++] Smart Pointer  (0) 2012.04.25
Android Framework 분석을 위한 C++ 3일차  (0) 2012.04.25
swap 함수  (0) 2012.04.25
Posted by code cat
프로그래밍/C++2012. 4. 25. 20:04

스마트 포인터란?

 

스마트 포인터는 다른 객체의 포인터 역활을 하는 객체이다.  여기서 중요한 것은 '포인터가 아닌' '객체'이다.

예제를 보자.

 

스마트 포인터가 추가되면 다음과 같다.

sp를 보면 포인터는 아닌데, sp->goo()를 하는 걸 보면 포인터 같기도 하고, 헷갈린다?

우선 Sptr sp = new Obj 는 Sptr sp(new Obj)와 같다.   C++에서 객체의 대입, a = new b 는 a(new b)라고 생각해도 무방하다.  Sptr의 생성자를 보면 Obj* p를 인자로 받고, Obj* s_obj를 p로 초기화 시켜준다.  결국 sp는 Obj* 를 멤버로 갖는 객체가 생성된 것이다. 

 

그럼 ->는 무엇인가?  그것은, 연산자 오버로딩을 통해 구현된 것이다.

 

Obj* operator->()   { return s_obj; }

 

결국엔 Obj* 타입인 s_obj를 리턴하는 것이다. 그럼 결국엔,

 

sp->goo()는  (sp.operator->())goo()

 

인 것이고 sp.operator->()는 Obj*를 리턴함으로,

 

(sp.operator->())->foo()로 해석하게 되어 마치 포인터로 함수를 호출하는 거처럼 작동한다.

 

다시 말해 스마트 포인터(sp)는 객체이지만 마치 다른 객체(Obj)의 포인터(Obj*)역활을 한다.

 

 

 

 

레퍼런스 카운팅

 

위에서 보다싶이, 내부적으로 포인터 변수를 가지고 있으므로, 얕은 복사(shallow copy)가 발생할 확률이 높다.

물론 이를 방지하기 위해, 깊은 복사(deep copy)를 구현할 수도 있으나, 이는 성능이슈 및 스마트(?)하지 않으므로, 대신 레퍼런스 카운팅 기법을 쓰는게 좋다.

 

 

'프로그래밍 > C++' 카테고리의 다른 글

cout , endl 의 원리  (0) 2012.04.28
Android Framework 분석을 위한 C++ 4일차  (0) 2012.04.26
Android Framework 분석을 위한 C++ 3일차  (0) 2012.04.25
swap 함수  (0) 2012.04.25
Android Framework 분석을 위한 C++ 2일차  (0) 2012.04.24
Posted by code cat
프로그래밍/C++2012. 4. 25. 11:55

1. cout, endl의 원리

 

cout은 원래 객체이며, endl의 경우 함수이다.  아래는 cout과 endl를 구현해 본 소스코드이다.

 

추가로 tab이나 two_endl의 사용자정의 함수도 추가했다. 

 

그럼 이게 기존거랑 충돌이 나느냐? 아래를 보자.

위와 같이 우리가 만든 함수들도 기존 std 네임스페이스와 같이 쓸 수 있다.

 

cout은 c와 달리 출력 형태가 무엇인지 정해주지 않아도 된다. 그렇다면 사용자 정의 객체 일 경우 어떻게 해야 할까?

아래는 사용자 정의 객체인 Point를 만든 코드이다.

 

cout << p;  이 부분은 결국 cout.operator<<(Point)가 있으면 된다.

 

만약 namespace를 쓴다면, 어떨까? cout은 이미 라이브러리에서 정의된 것인데, Graphic::을 붙일 수 없지 않은가?

그래서 2일차에서 나왔던 키네그 룩업이라는 기법을 써서, 어차피 Point라는 객체가 존재하는 namespace를 찾아서 쓸 수 있게 하는 것이다.

이런 문법들이 왜 이렇게 설계되었는지 더 자세히 알고 싶으면, Annoted Reference Manual : C++을 참조하라.

 

 

2. 변환 연산자

 

 

 

변환 연산자를 생성하면 된다.  변환 생성자도 추가됐다.

 

 

 

 

 

 

3. new 연산자 이야기

 

 

new를 오버로딩하는 것도 가능하다.

 

memory leak 검사하기

 

 

placement new 개념

// placement new 개념
// 1. 기존의 메모리에 대해서 생성자를 호출할 때 사용하는 기술
// 2. new(기존메모리 주소) 타입;
// 3. C로  할당한 메모리(공유메모리등)을 객체처럼 사용하려고...
// 4. 또는 Template을 활용한 고성능 라이브러리 만들 때 주로 사용
//    안드로이드의 typehelpers.h 가 이 기술 사

 

분명히 new에서는 메모리 할당을 하지 않았음에도 불고하고, 객체를 리턴함으로써 생성자/소멸자를 호출한다.(확인)

 

 

 

 

안드로이드에서는 프로세스간 Binder를 써서 통신하는데, 이때 쓰는게 mmap이다. 이와 비슷하게

 

 

이제 new와 예외처리에 대해서 알아보자.

 

멀쩡해 보이나?  1998년 이후, new가 실패 했을 경우, 더 이상 0을 리턴하지 않는다.

 

대신 다음과 같이 try... catch블록을 써서 체크해야 한다.

 

 

 

만약 아래와 같이 메모리가 부족하면, p2의 생성자는 소멸이 되는가??

 

안된다. 완전하게 끝난 생성자만 소멸이 가능하다.

 

그래서 두가지 해결책이 있다.

첫째로 스마트 포인터를 사용한다.

 

두번째로 생성자에서 자원을 할당하지 말고 자원할당 전용함수를 만들어 사용한다.

 

전체적인 소스는 다음과 같다.

 

 

4. 함수객체

 

함수객체에 대해서 알아보자.

 

예제처럼, 객체를 함수처럼 연산자 오버로딩을 통해서 사용할 수 있다.

 

전에 함수포인터는 inline 치환이 불가능했었는데, 함수객체를 사용하면, 가능하게 된다.(예제만 설명하느라 컴파일은 안된다)

함수객체의 장점은 즉, inline함수를 쓸 수 있으니, 빠르다는 점이 있겠다

 

sort를 통해서 함수객체에 대해서 더 알아보자.

 

좀 더 다듬어 보자.

 

 

 

쉬어가는 코너

 

 

5. STL

아래의 코드를 참조하자.

 

6. 상속

생성자는 부모 먼저 불리우고, 자식의 생성자가 불리며 소멸자는 반대의 순서이다.

Dog()에서 비록 우리가 아무런 부모생성자 호출 코드를 안 넣었어도 컴파일러가 Dog() : Animal() { ...} 이런 식으로 추가해 준다.  즉 부모 생성자가 먼저 만들어지더다라도, 자식 생성자가 먼저 호출은 된다.

 

protected에 대한 문제

protected 생성자는 자신은 만들 수 없지만, 자식은 만들 수 있게 하는 기술.

 

어떤 관계로 상속 받았냐에 따라서 자식이 물려받은 변수에 영향을 미친다.

 

근데 왜 private을 쓸까? (정말 몰라서 묻는건 아니고, 다음 예제를 보자는 말이다)

 

Vector클래스의 상속권한을 private으로 바꾸자.

 

 

7. Upcasting

자식 클래스는 public으로 상속 받았을 경우, 부모가 요구되는 인자에 자식 클래스로서 갈 수 있다.

좀 더 자세한 Upcating에 대한 소스를 보자.

 

 

 

8. 함수 오버라이딩

 

부모의 함수가 적당하지 않을 때, 같은 이름의 함수로 오버라이드를 할 수 있다.

예를 들어,

Anima* p = &Dog;

라고 있을 때,

p->Cry()

라고 하면,

A:Cry(),

B:Cry()

중 어느 함수를 불러야 할지 결정하게 되는데 이를 바인딩이라고 한다.

 

바인딩(binding)은 다음의 두 종류가 있다.

 static binding(early binding) 

 컴파일러가 컴파일시간에 결정. 원리는 포인터 타입으로 호출

 c++, c#

 dynamic binding(late binding)  컴파일러가 컴파일시 메모리 조사하는 코드를 생성.  실행시 메모리에 어떤 객체가 있는지 조사해서 호출
 java, objective-c, c++(virtual), c#(virtual)

 

관련된 코드는 아래를 참조하자.

 

 

마지막으로 OOP 개념을 살린 예제 코드 한번 보자.(두번 보자)

 

 

   모든 자식에 공통의 전체 알고리즘은 부모가 제공한다.
   하지만 변경되어야 하는 세부 알고리즘은 protected 가상함수로 제공한다.
   전체 알고리즘함수에서 세부 알고리즘 함수를 호출해서 세부알고리즘은 자식이 변경 할 수 있게 하자!

Binder의 Iinterface내에 이 디자인 패턴을 사용했다.

'프로그래밍 > C++' 카테고리의 다른 글

Android Framework 분석을 위한 C++ 4일차  (0) 2012.04.26
[C++] Smart Pointer  (0) 2012.04.25
swap 함수  (0) 2012.04.25
Android Framework 분석을 위한 C++ 2일차  (0) 2012.04.24
Android Framework 분석을 위한 C++ 1일차  (0) 2012.04.23
Posted by code cat
프로그래밍/C++2012. 4. 25. 00:39

갑자기 생각나서...

Posted by code cat
프로그래밍/C++2012. 4. 24. 10:52

이 글의 모든 소스는 Android Framework 분석을 위한 C++ 강좌에 사용된 코드이며 저에겐 코드에 대해 아무런 권리도 없음을 밝힙니다.

 

1. 초기화 리스트(Colon Initialize)

 

클래스 멤버로로 상수나 참조 멤버가 있는 경우, 반드시 초기화리스트로 초기화해야 한다.

 

만약 디폴트 생성자가 없는 객체를 멤버로 가질 때 초기화 리스트로 초기화 해야 한다.

 

주의할 점은, 초기화는 클래스의 멤버가 선언된 순서대로 초기화 된다.

 

참고로 생성자를 클래스 외부에 구현했을 때 초기화 리스트는 다음 줄에 표기하자.

 

 

2. 상수 함수

상수 함수가 필요한 이유

 

우선 다음과 같은 코드를 보자.

 

근데 뭐 나는 const가 들어 갈 함수 안에 값을 안 바꿀거니, const 따위 필요 없다! 라고 생각하고 한번 제외하고 코드를 짜보자. 그러면 , print는 안에 아무것도 변하지 않으니 실행될 거 같지만?.. 안된다!

상수 객체는 상수 함수만 호출 할 수 있다.

 

그러면 뭐 난 상수랑 안 쓰겠다? 하면 될까? 다음 코드를 보자.

 

결론은 라이브러리 제작이나 완전한 클래스를 제공할려면 const를 만들어야 한다.

간단한 룰은 값을 변하게 하는 함수라면 const가 필요 없으나, 그 외에는 const를 붙여야 한다.

 

 

3. 복사 생성자

 

 

다음의 코드를 실행하면 결과가 어떻게 나올까?

 

결과는 다음과 같다.

 start
 생성자2
 AAA
 복사생성자 - p
 foo
 소멸자 - p
 BBB
 소멸자

 

여기서 다시 성능향상을 위해서 다음과 같이 수정하자.

 

 

다음 코드의 결과를 예측해 보자.

 

결과는 다음과 같다.

 start
 생성자1 - p1
 AAA
 생성자2 - p2
 foo
 복사생성자 - 임시객체
 소멸자 - p2
 소멸자 - 임시객체
 BBB
 소멸자

 

다시 성능 향상을 위해 임시객체에 대한 작업을 하려고 하지만, 예전과 달리 이번에는 전역객체가 아닌 지역객체를 리턴함으로, 다음과 같이 하면 안된다. (지역변수등을 리턴할 때, 참조를 쓰면 안된다.)

 

대신 RVO를 써서, 다음과 같이 바꾸면 된다.

 

한가지 주의할 점은, 만약에 우리가 복사생성자를 다음과 같이 만들었다고 치자(성능은 잠시 접어두고)

복사 생성자가 인자로 디폴트를 넘기는 이게 또 복사 생성자를 부르고 하는 무한 반복 코드가 되서 컴파일 에러가 난다.

 

 

복사 생성자는 또 디폴트 복사 생성자에 대한 문제점이 있는 해결책은 다음의 4가지이다.

    (A) 깊은 복사    - 가장 널리 알려진 기술. 하지만 별로 좋지 않다.   

    (B) 참조 계수    - 가장 많이 사용하고, 가장 좋은 기술
    (C) 소유권 이전 - 많이 사용하고 있진 않지만 swap등을 만들 때 좋다.
                             STL의 auto_ptr<>이 이 기술 사용
    (D) 복사 금지

 

우선 기본적으로 얕은 복사 때문에 생기는 문제의 코드다.

 

깊은 복사 (성능의 문제가 있다)

 

참조계수(Referecen Counting)

 

소유권 이전 (살짝 헷갈리는 부분)

 

복사 금지

 

 

 

4. 싱글톤

오직 한개의 객체만을 만드는 디자인 패턴

 

우선 기본적인 코드를 보자.

 

이번엔 객체를 힙으로 만들자.

 

 

만약 우리가 Cursor말고도 KeyBoard라는 클래스를 똑같이 만들고 싶다면, 다음과 같이 코드 자동 생성을 작성해 보자.

 

 

 

아쉽게도 안드로이드에서는 템플릿을 응용한 기술 + 상속 기술을 사용한다. (템플릿이 조금 어렵게 구현된다) 이런한 기술을 mix in template이라고 한다.

 

 

 

5. This

 

기본적인 this의 사용법이다.  여기서 cout또한 this를 이용한 것을 볼 수 있다.

 

p1, p2처럼 2개의 Point를 생성하면, 각 멤버 data는 객체마다 존재하지만, 코드는 공유를 한다. 그럼 어떻게 멤버 함수가 불리울 때, 어느 객체인지 알 수 있을까?

위와 같이 컴파일 시에는 객체에 대한 인자를 넘길 수 있는 형태로 변환된다.  추가적으로 static의 경우 this가 필요치 않고, 사용할 수 없다.

 

 

6. 멤버 함수 포인터

 

 

 

 

 

 

 

7. 연산자 재정의

 

 

위의 코드에서 보면, 멤버 함수와 일반 함수의 용도에 따라 약간 다른 컴파일 결과가 나오는데,

일반 함수 vs 멤버 함수는 쉽게 생각해서, 연산의 결과로 멤버가 바뀔 거면(private이면) 일반함수에 접근이 불가능하기 때문에 멤버 함수로 하는게 좋고, 아닐 경우, 일반 함수로 하면 좋겠다. 

 

증감연산도 보자.

우리가 만든 Int32도 당연히 ++가 잘 동작해야 한다. 하지만 오동작을 하는 것을 볼 수 있다( 5가 나오는 대신 4)

 

이를 수정하려면, 참조리턴을 해야 한다.

 

마찬가지로 후위형 또한 다음과 같이 할 경우가 문제 생기는데,

 

이를 수정하려면, 다음과 같이 한다.

한번 보면, (n2.operator++(int))는 Int32 n2가 상수가 아니기에 const Int32 operator++를 부르는데 문제가 없으나, 이를 통해 리턴되는 녀석은 상수(const)이다. 그럼 다시 (n2.operator++(int)).operator++(int)를 부르라고 하면, %상수 객체는 상수 함수만을 부를 수 있다%, 상수라서 부를 수 없다.

 

그리고 성능 향샹을 위해 전위형은 inline으로, 후의형은 다시 전위형을 호출하게 하자.

 

이걸로 보면 전위형이 후위형보다 성능이 좋다는 걸 알 수 있다.

for(int i = 0; i < 10; i++) 보다 for(int i = 0; i < 10; ++i)가 좋다는 말이다. 그러나 역시 똑똑한 우리의 컴파일러는 컴파일 시 이를 최적화 해 주므로 가독성을 위해 i++을 써도 된다.

 

 

8 스마트 포인터

 

스마트 포인터를 설명하기 위한 기본 코드를 보자.

 

변형을 조금 가해서 코드가 조금 어려워 진다.

sptr p를 보면.. sptr은 포인터가 아니고, sptr 타입인데, p->Go()를 보면 포인터같고 Car타입 같다.. >_<

sptr 안에는 Car* 포인터가 존재하고 sptr p = new Car 는 결구 sptr p(new Car)와 같다.

p->Go()의 경우 위에 정의된  operator->()에 따른다.

 

이것이 스마트 포인터라고 불리우는데, 이는 포인터가 아닌 객체(다른 객체의 포인터 역활을 한다.)이며, 스마트 포인터의 장점은 생성/복사/대입/소멸의 모든 과정을 사용자가 정의 할 수 있다는 것이다.

 

아래는 template을 써서 위의 sptr을 일반화한 코드이다.

 

스마트 포인터와 참조계수에 대해서 알아보자.

 

 

그러나 스마트포인터는 레퍼런스카운터에 대한 포인터 때문에 오버헤드가 있다. 그럼 레퍼런스를 객체에 두어보자.

 

 

마지막으로 안드로이드에서 쓰는 방식을 따라서 써 본 코드이다.

안드로이드는 객체가 만들어지면 레퍼런스 카운터가 1이 되고, 스마트 포인터로 가리키면 2가 된다.(보통 0에서 시작해서 스마트 포인터가 가리키면 1이된다).

 

 

9. 반복자

 

 

 

 

 

 

 

 

'프로그래밍 > C++' 카테고리의 다른 글

Android Framework 분석을 위한 C++ 4일차  (0) 2012.04.26
[C++] Smart Pointer  (0) 2012.04.25
Android Framework 분석을 위한 C++ 3일차  (0) 2012.04.25
swap 함수  (0) 2012.04.25
Android Framework 분석을 위한 C++ 1일차  (0) 2012.04.23
Posted by code cat