'C,C++ '에 해당되는 글 59건

  1. 2014.09.16 heap sorting sorce
  2. 2014.07.02 [ attribute 관련 속성 정리 ]
  3. 2014.05.02 [ OPEN CV ] 카메라 화면 띄우기
  4. 2014.05.02 [ kernel ] 루트킷 분석하다가 조사한 커널 함수들.
  5. 2014.04.24 LINUX dlopen 으로 dynamic 하게 library 호출
  6. 2013.03.19 리눅스 pthread 사용시 라이브러리 추가 옵션.
  7. 2012.11.28 C opt 줘서 argv 인자값을 옵션화 시키기 getopt 옵션
  8. 2012.08.20 MYSQL C 언어로 BLOB 타입에 파일을 입출력 시키기
  9. 2012.08.19 C++ string 값을 char* 로 바꾸기.
  10. 2012.08.19 Jsoncpp 사용하기 ! 설치?법(?) 포함 빌드하기
  11. 2012.08.17 [SSM 안드로이드 프레임워크 개발 강의]32. 클라이언트에서 바인더로 통신방법의 원리
  12. 2012.08.16 [SSM 안드로이드 프레임워크 개발 강의]31. 퍼팩트 포워딩
  13. 2012.08.16 [SSM 안드로이드 프레임워크 개발 강의]30.Traits (타입 판독 STL)
  14. 2012.08.16 [SSM 안드로이드 프레임워크 개발 강의]29. 템플릿이야기3 (멤버함수 템플릿)
  15. 2012.08.16 [SSM 안드로이드 프레임워크 개발 강의]28. 템플릿이야기 2(클래스 템플릿)
  16. 2012.08.16 [SSM 안드로이드 프레임워크 개발 강의]27. 템플릿이야기 1
  17. 2012.08.16 [SSM 안드로이드 프레임워크 개발 강의]26. RTTI , RTCI 직접 구현해보기
  18. 2012.08.16 [SSM 안드로이드 프레임워크 개발 강의]25. RTTI 이야기
  19. 2012.08.16 [SSM 안드로이드 프레임워크 개발 강의]24. 가상 소멸자 이야기
  20. 2012.08.16 [SSM 안드로이드 프레임워크 개발 강의]23. 가상함수의 원리와 함수포인터이해
  21. 2012.08.15 [SSM 안드로이드 프레임워크 개발 강의]22. 범용적 함수 포인터와 bind
  22. 2012.08.15 [SSM 안드로이드 프레임워크 개발 강의]21. 인터페이스와 인터페이스 탄생 배경
  23. 2012.08.15 [SSM 안드로이드 프레임워크 개발 강의]20. 접근변경자와 어뎁터 패턴
  24. 2012.08.15 [SSM 안드로이드 프레임워크 개발 강의]19. 메모리 릭을 체크하는 헤더만들기(operator New , Delete)
  25. 2012.08.15 [SSM 안드로이드 프레임워크 개발 강의]18. New 연산자 이야기
  26. 2012.08.14 [SSM 안드로이드 프레임워크 개발 강의]17. 변환 연산자와 변환 생성자. 그리고 활용.
  27. 2012.08.14 [SSM 안드로이드 프레임워크 개발 강의]16. STL 과 함수객체
  28. 2012.08.14 [SSM 안드로이드 프레임워크 개발 강의]15. STL find, strchr 구현하기
  29. 2012.08.14 [SSM 안드로이드 프레임워크 개발 강의]14-3.실제로 안드로이드 프레임웤에서 사용되는 스마트 포인터
  30. 2012.08.14 [SSM 안드로이드 프레임워크 개발강의]14-2 스마트포인터의 얕은복사 해결과 템플릿
2014. 9. 16. 15:34


힙소팅 정리한 소스 heap sorting sorce 



#include <stdio.h>

#include <stdlib.h>

#include <time.h>

#define SIZE 10                    // 배열 사이즈 정의


void create_random_data( int heap_array[], int size );

void display( int array[],int size );

void reverse_display( int array[], int size );


void create_heap_tree( int heap_array[] , int size );

void swap( int heap_array[], int index );

void heap_sorting( int heap_array[], int sort_array[] , int size );

int swap_sort( int heap_array[] , int size );

int min( int a , int b );


void main() {

clock_t start,finish;                       

int heap_array[SIZE];

int sort_array[SIZE];


/*random create */

printf("<< Random Data >>\n");

create_random_data(heap_array,SIZE);  //랜덤 데이타 생성

display(heap_array,SIZE);     


create_heap_tree(heap_array,SIZE);   //힙 트리 생성

printf("\n<< Create_heap_tree Data >>\n");

display(heap_array,SIZE);


heap_sorting(heap_array,sort_array,SIZE);   //힙 소팅 함수 호출

printf("\n<< Sorted Data >>\n");

display(sort_array,SIZE);


printf("\n<< Reverse Sorted Data >>\n");

reverse_display(sort_array,SIZE);


printf("\n");


}


void create_random_data(int heap_array[], int size) {

int i;

for(i=0 ; i<size ; i++)

heap_array[i] = rand()%size*3;

}


////////////////////////////////////////////////////////////////

//함수명 : display

//용도      : 배열을 출력한다.

//매개변수  : 배열 포인터,배열 사이즈

//리턴값    : 출력시간(정수)

void display(int array[], int size) {

int i;

for(i=0 ; i<size ; i++)

printf("%d ",array[i]);

printf("\n");

}


void reverse_display(int array[], int size) {

int i;

for(i=size-1 ; i>=0 ; i--)

printf("%d ",array[i]);

}


void create_heap_tree(int heap_array[], int size) {

int i;

for(i=1 ; i<size ; i++)

swap(heap_array,i);

}


/*create Heap 에 사용 되며, 상위 노드가 하위 노드보다는 반드시 작도록 배치한다.*/

void swap(int heap_array[], int index) {

int temp;

int swap_flag = 1;


while(swap_flag && index != 0) {    //루트 이거나 swap이 일어나지 않으면 종료

swap_flag = 0;     //swap을 감시하는 플래그


//index%2 == 1 이면 좌측 자식이다 (현재가 자식이다.. 루트이면 그냥 넘어감)

if(index%2 == 1 && heap_array[index] < heap_array[(index-1)/2]) {

heap_array[index] = heap_array[index] ^ heap_array[(index-1)/2];

heap_array[(index-1)/2] = heap_array[index] ^ heap_array[(index-1)/2];

heap_array[index] = heap_array[index] ^ heap_array[(index-1)/2];


index = (index-1)/2;

swap_flag = 1;

}

//index%2 == 0 이면 우측 자식이다(현재가 자식이다.. 루트이면 그냥 넘어감)

if(index%2 == 0 && heap_array[index] < heap_array[(index-2)/2]) {

heap_array[index] = heap_array[index] ^ heap_array[(index-2)/2];

heap_array[(index-2)/2] = heap_array[index] ^ heap_array[(index-2)/2];

heap_array[index] = heap_array[index] ^ heap_array[(index-2)/2];


index = (index-2)/2;

swap_flag = 1;

}

}

}




/* 힙트리의 배열에서 루트값을 빼내면서 소팅한다 */

void heap_sorting( int heap_array[], int sort_array[], int size ) {

int i = 0;

int heap_array_size;

heap_array_size = size;


for( i=0 ; i<size ; i++ ) {

sort_array[i] = swap_sort( heap_array, heap_array_size );

heap_array_size--; 

}


}

/* 최상위 root가 제일 작도록 소팅함. root 값에 최 하위 값 (상대적으로 큰값)

을 넣고 자식 노드와 비교해가며 정렬함 */

int swap_sort(int heap_array[], int size) {

int sort_value;

int swap_flag = 0;

int i = 0;

/* swap이 발생하지 않거나 인덱스가 size를 초과 하면 종료한다 */

while( swap_flag == 0 && !( ((i*2)+1 >= size-1) && ( (i*2)+2 >=size-1) ) ) {


swap_flag = 1;

///////////////////////////////////////////////////////////////////

// 좌 우 자식중 더 작은값(min함수 호출)과 비교한다

// 작은 값이 없다면.. 리턴! why? 힙소팅 create 부분에서 이미 상위

// 노트가 하위 노드보다는 반드시 작도록 설정 되었기 때문! 

// 좌 우 중 작은쪽이 있다면 작은 쪽의주로 정렬을 해 드러간다.

if( heap_array[i] > min( heap_array[(i*2)+1] , heap_array[(i*2)+2] )) 

{

if(heap_array[(i*2)+1] < heap_array[(i*2)+2]) {

heap_array[i] = heap_array[i] ^ heap_array[(i*2)+1];

heap_array[(i*2)+1] = heap_array[i] ^ heap_array[(i*2)+1];

heap_array[i] = heap_array[i] ^ heap_array[(i*2)+1];

i = (i*2)+1;

}

else {

heap_array[i] = heap_array[i] ^ heap_array[(i*2)+2];

heap_array[(i*2)+2] = heap_array[i] ^ heap_array[(i*2)+2];

heap_array[i] = heap_array[i] ^ heap_array[(i*2)+2];

i = (i*2)+2;

}

swap_flag = 0;

}// end if


}// end while



/* 젤 작은 root 값을 넘겨주고, root는 현트리의 제일 마지막 노드로 교체됨 */

sort_value = heap_array[0];

heap_array[0] = heap_array[size-1]; 

return sort_value;

}


int min(int a, int b) {

if(a < b) return a;

else return b;

}




Posted by k1rha
2014. 7. 2. 11:40

Declaring Attributes of Functions

In GNU C, you declare certain things about functions called in your program which help the compiler optimize function calls and check your code more carefully.

The keyword __attribute__ allows you to specify special attributes when making a declaration. This keyword is followed by an attribute specification inside double parentheses. The following attributes are currently defined for functions on all targets: noreturn,noinlinealways_inlinepureconstformatformat_argno_instrument_functionsectionconstructordestructorusedunuseddeprecatedweakmalloc, and alias. Several other attributes are defined for functions on particular target systems. Other attributes, includingsection are supported for variables declarations (see Variable Attributes) and for types (see Type Attributes).

You may also specify attributes with __ preceding and following each keyword. This allows you to use them in header files without being concerned about a possible macro of the same name. For example, you may use __noreturn__ instead of noreturn.

See Attribute Syntax, for details of the exact syntax for using attributes.

noreturn
A few standard library functions, such as abort and exit, cannot return. GCC knows this automatically. Some programs define their own functions that never return. You can declare them noreturn to tell the compiler this fact. For example,
          void fatal () __attribute__ ((noreturn));
          
          void
          fatal (...)
          {
            ... /* Print error message. */ ...
            exit (1);
          }
          

The noreturn keyword tells the compiler to assume that fatal cannot return. It can then optimize without regard to what would happen if fatal ever did return. This makes slightly better code. More importantly, it helps avoid spurious warnings of uninitialized variables.

Do not assume that registers saved by the calling function are restored before calling the noreturn function.

It does not make sense for a noreturn function to have a return type other than void.

The attribute noreturn is not implemented in GCC versions earlier than 2.5. An alternative way to declare that a function does not return, which works in the current version and in some older versions, is as follows:

          typedef void voidfn ();
          
          volatile voidfn fatal;
          

noinline
This function attribute prevents a function from being considered for inlining. 
always_inline
Generally, functions are not inlined unless optimization is specified. For functions declared inline, this attribute inlines the function even if no optimization level was specified. 
pure
Many functions have no effects except the return value and their return value depends only on the parameters and/or global variables. Such a function can be subject to common subexpression elimination and loop optimization just as an arithmetic operator would be. These functions should be declared with the attribute pure. For example,
          int square (int) __attribute__ ((pure));
          

says that the hypothetical function square is safe to call fewer times than the program says.

Some of common examples of pure functions are strlen or memcmp. Interesting non-pure functions are functions with infinite loops or those depending on volatile memory or other system resource, that may change between two consecutive calls (such as feof in a multithreading environment).

The attribute pure is not implemented in GCC versions earlier than 2.96. 

const
Many functions do not examine any values except their arguments, and have no effects except the return value. Basically this is just slightly more strict class than the pure attribute above, since function is not allowed to read global memory.

Note that a function that has pointer arguments and examines the data pointed to must not be declared const. Likewise, a function that calls a non-const function usually must not be const. It does not make sense for a const function to return void.

The attribute const is not implemented in GCC versions earlier than 2.5. An alternative way to declare that a function has no side effects, which works in the current version and in some older versions, is as follows:

          typedef int intfn ();
          
          extern const intfn square;
          

This approach does not work in GNU C++ from 2.6.0 on, since the language specifies that the const must be attached to the return value. 

format (archetypestring-indexfirst-to-check)
The format attribute specifies that a function takes printfscanfstrftime or strfmon style arguments which should be type-checked against a format string. For example, the declaration:
          extern int
          my_printf (void *my_object, const char *my_format, ...)
                __attribute__ ((format (printf, 2, 3)));
          

causes the compiler to check the arguments in calls to my_printf for consistency with the printf style format string argument my_format.

The parameter archetype determines how the format string is interpreted, and should be printfscanfstrftime or strfmon. (You can also use __printf____scanf____strftime__ or __strfmon__.) The parameter string-index specifies which argument is the format string argument (starting from 1), while first-to-check is the number of the first argument to check against the format string. For functions where the arguments are not available to be checked (such as vprintf), specify the third parameter as zero. In this case the compiler only checks the format string for consistency. For strftime formats, the third parameter is required to be zero.

In the example above, the format string (my_format) is the second argument of the function my_print, and the arguments to check start with the third argument, so the correct parameters for the format attribute are 2 and 3.

The format attribute allows you to identify your own functions which take format strings as arguments, so that GCC can check the calls to these functions for errors. The compiler always (unless -ffreestanding is used) checks formats for the standard library functions printffprintfsprintfscanffscanfsscanfstrftimevprintfvfprintf and vsprintf whenever such warnings are requested (using -Wformat), so there is no need to modify the header file stdio.h. In C99 mode, the functions snprintf,vsnprintfvscanfvfscanf and vsscanf are also checked. Except in strictly conforming C standard modes, the X/Open function strfmon is also checked as are printf_unlocked and fprintf_unlocked. See Options Controlling C Dialect

format_arg (string-index)
The format_arg attribute specifies that a function takes a format string for a printfscanfstrftime or strfmon style function and modifies it (for example, to translate it into another language), so the result can be passed to a printfscanfstrftime or strfmonstyle function (with the remaining arguments to the format function the same as they would have been for the unmodified string). For example, the declaration:
          extern char *
          my_dgettext (char *my_domain, const char *my_format)
                __attribute__ ((format_arg (2)));
          

causes the compiler to check the arguments in calls to a printfscanfstrftime or strfmon type function, whose format string argument is a call to the my_dgettext function, for consistency with the format string argument my_format. If the format_arg attribute had not been specified, all the compiler could tell in such calls to format functions would be that the format string argument is not constant; this would generate a warning when -Wformat-nonliteral is used, but the calls could not be checked without the attribute.

The parameter string-index specifies which argument is the format string argument (starting from 1).

The format-arg attribute allows you to identify your own functions which modify format strings, so that GCC can check the calls to printfscanfstrftime or strfmon type function whose operands are a call to one of your own function. The compiler always treats gettextdgettext, and dcgettext in this manner except when strict ISO C support is requested by -ansi or an appropriate -std option, or -ffreestanding is used. See Options Controlling C Dialect

no_instrument_function
If -finstrument-functions is given, profiling function calls will be generated at entry and exit of most user-compiled functions. Functions with this attribute will not be so instrumented. 
section ("section-name")
Normally, the compiler places the code it generates in the text section. Sometimes, however, you need additional sections, or you need certain particular functions to appear in special sections. The section attribute specifies that a function lives in a particular section. For example, the declaration:
          extern void foobar (void) __attribute__ ((section ("bar")));
          

puts the function foobar in the bar section.

Some file formats do not support arbitrary sections so the section attribute is not available on all platforms. If you need to map the entire contents of a module to a particular section, consider using the facilities of the linker instead. 

constructor
destructor
The constructor attribute causes the function to be called automatically before execution enters main (). Similarly, the destructor attribute causes the function to be called automatically after main () has completed or exit () has been called. Functions with these attributes are useful for initializing data that will be used implicitly during the execution of the program.

These attributes are not currently implemented for Objective-C. 

unused
This attribute, attached to a function, means that the function is meant to be possibly unused. GCC will not produce a warning for this function. GNU C++ does not currently support this attribute as definitions without parameters are valid in C++. 
used
This attribute, attached to a function, means that code must be emitted for the function even if it appears that the function is not referenced. This is useful, for example, when the function is referenced only in inline assembly. 
deprecated
The deprecated attribute results in a warning if the function is used anywhere in the source file. This is useful when identifying functions that are expected to be removed in a future version of a program. The warning also includes the location of the declaration of the deprecated function, to enable users to easily find further information about why the function is deprecated, or what they should do instead. Note that the warnings only occurs for uses:
          int old_fn () __attribute__ ((deprecated));
          int old_fn ();
          int (*fn_ptr)() = old_fn;
          

results in a warning on line 3 but not line 2.

The deprecated attribute can also be used for variables and types (see Variable Attributes, see Type Attributes.) 

weak
The weak attribute causes the declaration to be emitted as a weak symbol rather than a global. This is primarily useful in defining library functions which can be overridden in user code, though it can also be used with non-function declarations. Weak symbols are supported for ELF targets, and also for a.out targets when using the GNU assembler and linker. 
malloc
The malloc attribute is used to tell the compiler that a function may be treated as if it were the malloc function. The compiler assumes that calls to malloc result in a pointers that cannot alias anything. This will often improve optimization. 
alias ("target")
The alias attribute causes the declaration to be emitted as an alias for another symbol, which must be specified. For instance,
          void __f () { /* do something */; }
          void f () __attribute__ ((weak, alias ("__f")));
          

declares f to be a weak alias for __f. In C++, the mangled name for the target must be used.

Not all target machines support this attribute. 

regparm (number)
On the Intel 386, the regparm attribute causes the compiler to pass up to number integer arguments in registers EAX, EDX, and ECX instead of on the stack. Functions that take a variable number of arguments will continue to be passed all of their arguments on the stack. 
stdcall
On the Intel 386, the stdcall attribute causes the compiler to assume that the called function will pop off the stack space used to pass arguments, unless it takes a variable number of arguments.

The PowerPC compiler for Windows NT currently ignores the stdcall attribute. 

cdecl
On the Intel 386, the cdecl attribute causes the compiler to assume that the calling function will pop off the stack space used to pass arguments. This is useful to override the effects of the -mrtd switch.

The PowerPC compiler for Windows NT currently ignores the cdecl attribute. 

longcall
On the RS/6000 and PowerPC, the longcall attribute causes the compiler to always call the function via a pointer, so that functions which reside further than 64 megabytes (67,108,864 bytes) from the current location can be called. 
long_call/short_call
This attribute allows to specify how to call a particular function on ARM. Both attributes override the -mlong-calls (see ARM Options) command line switch and #pragma long_calls settings. The long_call attribute causes the compiler to always call the function by first loading its address into a register and then using the contents of that register. The short_call attribute always places the offset to the function from the call site into the BL instruction directly. 
dllimport
On the PowerPC running Windows NT, the dllimport attribute causes the compiler to call the function via a global pointer to the function pointer that is set up by the Windows NT dll library. The pointer name is formed by combining __imp_ and the function name. 
dllexport
On the PowerPC running Windows NT, the dllexport attribute causes the compiler to provide a global pointer to the function pointer, so that it can be called with the dllimport attribute. The pointer name is formed by combining __imp_ and the function name. 
exception (except-func [, except-arg])
On the PowerPC running Windows NT, the exception attribute causes the compiler to modify the structured exception table entry it emits for the declared function. The string or identifier except-func is placed in the third entry of the structured exception table. It represents a function, which is called by the exception handling mechanism if an exception occurs. If it was specified, the string or identifier except-arg is placed in the fourth entry of the structured exception table. 
function_vector
Use this attribute on the H8/300 and H8/300H to indicate that the specified function should be called through the function vector. Calling a function through the function vector will reduce code size, however; the function vector has a limited size (maximum 128 entries on the H8/300 and 64 entries on the H8/300H) and shares space with the interrupt vector.

You must use GAS and GLD from GNU binutils version 2.7 or later for this attribute to work correctly. 

interrupt
Use this attribute on the ARM, AVR, M32R/D and Xstormy16 ports to indicate that the specified function is an interrupt handler. The compiler will generate function entry and exit sequences suitable for use in an interrupt handler when this attribute is present.

Note, interrupt handlers for the H8/300, H8/300H and SH processors can be specified via the interrupt_handler attribute.

Note, on the AVR interrupts will be enabled inside the function.

Note, for the ARM you can specify the kind of interrupt to be handled by adding an optional parameter to the interrupt attribute like this:

          void f () __attribute__ ((interrupt ("IRQ")));
          

Permissible values for this parameter are: IRQ, FIQ, SWI, ABORT and UNDEF. 

interrupt_handler
Use this attribute on the H8/300, H8/300H and SH to indicate that the specified function is an interrupt handler. The compiler will generate function entry and exit sequences suitable for use in an interrupt handler when this attribute is present. 
sp_switch
Use this attribute on the SH to indicate an interrupt_handler function should switch to an alternate stack. It expects a string argument that names a global variable holding the address of the alternate stack.
          void *alt_stack;
          void f () __attribute__ ((interrupt_handler,
                                    sp_switch ("alt_stack")));
          

trap_exit
Use this attribute on the SH for an interrupt_handle to return using trapa instead of rte. This attribute expects an integer argument specifying the trap number to be used. 
eightbit_data
Use this attribute on the H8/300 and H8/300H to indicate that the specified variable should be placed into the eight bit data section. The compiler will generate more efficient code for certain operations on data in the eight bit data area. Note the eight bit data area is limited to 256 bytes of data.

You must use GAS and GLD from GNU binutils version 2.7 or later for this attribute to work correctly. 

tiny_data
Use this attribute on the H8/300H to indicate that the specified variable should be placed into the tiny data section. The compiler will generate more efficient code for loads and stores on data in the tiny data section. Note the tiny data area is limited to slightly under 32kbytes of data. 
signal
Use this attribute on the AVR to indicate that the specified function is an signal handler. The compiler will generate function entry and exit sequences suitable for use in an signal handler when this attribute is present. Interrupts will be disabled inside function. 
naked
Use this attribute on the ARM or AVR ports to indicate that the specified function do not need prologue/epilogue sequences generated by the compiler. It is up to the programmer to provide these sequences. 
model (model-name)
Use this attribute on the M32R/D to set the addressability of an object, and the code generated for a function. The identifier model-name is one of smallmedium, or large, representing each of the code models.

Small model objects live in the lower 16MB of memory (so that their addresses can be loaded with the ld24 instruction), and are callable with the bl instruction.

Medium model objects may live anywhere in the 32-bit address space (the compiler will generate seth/add3 instructions to load their addresses), and are callable with the bl instruction.

Large model objects may live anywhere in the 32-bit address space (the compiler will generate seth/add3 instructions to load their addresses), and may not be reachable with the bl instruction (the compiler will generate the much slower seth/add3/jlinstruction sequence).

You can specify multiple attributes in a declaration by separating them by commas within the double parentheses or by immediately following an attribute declaration with another attribute declaration.

Some people object to the __attribute__ feature, suggesting that ISO C's #pragma should be used instead. At the time __attribute__ was designed, there were two reasons for not doing this.

  1. It is impossible to generate #pragma commands from a macro.
  2. There is no telling what the same #pragma might mean in another compiler.

These two reasons applied to almost any application that might have been proposed for #pragma. It was basically a mistake to use #pragma for anything.

The ISO C99 standard includes _Pragma, which now allows pragmas to be generated from macros. In addition, a #pragma GCC namespace is now in use for GCC-specific pragmas. However, it has been found convenient to use __attribute__ to achieve a natural attachment of attributes to their corresponding declarations, whereas #pragma GCC is of use for constructs that do not naturally form part of the grammar. See Miscellaneous Preprocessing Directives.

Posted by k1rha
2014. 5. 2. 22:22

OPEN CV 카메라 화면 띄우는 코드 


[ 관련 자료 : http://yonghello.tistory.com/148 ]

[ 설치 및 환경설정 자료 : http://mymnboy.egloos.com/viewer/987948 ]

http://www.microsoft.com/ko-kr/download/confirmation.aspx?id=40784


 

#include<opencv/cv.h>

#include<opencv/highgui.h>

 

using namespace cv;

 

int main()

{

          Mat image;

 

          /*동영상 파일이나 카메라를 통해 들어오는 영상의 캡쳐를 위한 클래스.*/

          VideoCapture cap;

          /*VideoCapture클래스의 인스턴스를 통해서 연결된 웹캠의 제어를 받는 부분.0이라는 숫자는 카메라의 id값이다.

             현재 연결된 내부 카메라(built in webcam)를 의미한다.하지만 외부에 웹캠이 따로 연결되면 그 웹캠의 id값이 0이 된다.*/

           cap.open(0);


          namedWindow("window", CV_WINDOW_AUTOSIZE);

           

           /*루프를 돌면서 프레임 단위로 이미지를 받아들이는 부분.*/

          while(1)

        {

                /*VideoCapture로 이미지 프레임 하나를 받아서 image변수로 넘김.*/

                 if(cap.read(image) == NULL)

              {

                     cout<<"frame was not read."<<endl;

              }

 

                 /*이미지 프레임을 윈도우를 통해서 스크린으로 출력.이 과정이 반복되면서 영상이 출력되게 된다.*/

                imshow("window", image);

 

               /*delay 33ms*/

               waitKey(33);

           }

         return 0;

}



Posted by k1rha
2014. 5. 2. 16:58

[ kernel ] 루트킷 분석하다가 조사한 커널 함수들.


Init_module : 커널함수의 시작은 main 대신 init_moudle 사용함.

IOCTL : read(), write() 와같이 읽기 쓰기 처리가 가능  -> 하드웨어의 제어나 상태를 얻기 위해 사용

Inet_add_protocol : 새로운 네트워크 프로토콜을 설정할수있음

Inet_del_protocol  : 기존 네트워크 프로토콜 삭제

create_proc_entry : proc 파일 시스템에서 접근   있는 파일을 만든다만들  있는 최상위 디렉토리는 /proc 이다. (구조체로 존재)

 

i_node 구조 (리눅스 디폴트 파일 시스템 ex2, ex3  채택)

  • i-mode : 파일의 속성  접근제어 정보 ( 정규파일 : S_IFREG , 디렉터리 : S_IFDIR , 장치파일 : S_IFCHR , 블록장치파일 : S_IFBLK , 파이프 : S_IFFIFO, 소켓 : S_IFSOCK

 

MODULE_PARM(char * modname, "s") // kernel 2.4 부터 insmod  인자를 받을  있도록 구성되었는데, s  문자열 형태를 받겠다는 

int gettimeofday(struct timeval *tv, struct timezone *tz);  :  timezone  설정함

copy_from_user(void * to, const void __user * from, unsigned long n)  :  사용자 메모리 블록 데이터를 커널 메모리 블록 데이터에  넣는다.

                                                                                             (from 사용자메모리, to 커널메모리)

 

nl->next = kmalloc(sizeof(struct nethide_list), GFP_KERNEL);

GFP_ATOMIC

메모리가 있으면 할당 없으면 NULL. 휴면 불가능

GFP_KERNEL

메모리 할당이 항상 성공하도록 요구, 메모리가 충분하지 않을 경우는 호출한 프로세스를 멈추고 동적 메모리 할당할 수 있는 상태가 될 때까지 대기. 휴면가능.

GFP_USER

유저 메모리를 할당함.  휴면 가능 

GFP_DMA

연속된 물리 메모리를 할당 받을 때 사용

 

 

즉, /dev/mem은 실제 물리 메모리, /dev/kmem은 커널 가상 메모리 공간에 접근할 수 있는 디바이스 파일입니다.

 

  • Hook, 우선순위1B Hook, 우선순위2C Hook, 우선순위 있을  nf_register_hook( D Hook, 우선순위2 ) 하면 아래처럼 
  • Hook, 우선순위1B Hook, 우선순위2 , D Hook, 우선순위,C Hook, 우선순위3

 

 

EXPORT_NO_SYMBOLS  :  전역 변수와 전역 함수를 커널 심볼 테이블에 등록해 놓음 ( 공개되지 않은 코드임 )

Dentry  ? : 해당 디렉토리가 포함하고 있는 디렉토리와 파일정보를 보유 하고 있음

 

 

Getdents()  Get directory entrys  : 디렉토리의 속성을 가져옴

query_module() : 함수를 이용해 커널 심볼 테이블과 커널에 적재된 다른 모듈의 심볼 테이블을 구한다이때 query_module() 함수에 QM_MODULES, QM_INFO, QM_SYMBOL 값을 지정하여 필요한 정보를 가져오는데, QM_MODULES는 커널에 포함된 모듈명을 얻어올 때 사용하며, QM_INFO는 각 모듈의 시작 주소와 크기를 얻기 위해 사용한다. 앞에서 구한 모듈 정보를 통해 QM_SYMBOL로 실질적인 커널 심볼 테이블과 커널에 적재된 다른 모듈의 심볼 테이블을 구한다

 

___this_module  : 현재 커널을 가리키고 있는 커널 내부 변수 

Ex)struct module *m = &__this_module;

 

Sysenter : sysenter가 호출되면 IA32_SYSENTER_EIP를 참고하여 KiFastCallEntry가 호출되는 것을 알 수 있었다.

커널 2.6 부터는 시스템 테이블을 그냥 오버라이딩   없기 때문에 나온 .

 

SSDT 후킹은 윈도우즈 API 가 커널 모드에서 서비스를 받기 위해 필요한 SSDT(System Service Descriptor Table) 의 내용을 조작하는 커널모드 후킹 방법 중에 하나 이다.

 

sysenter 명령은 유저모드에서 사용되는 명령어로, 현재 스레드가 유저모드에서 커널모드로 진입 시켜주는 역할을 한다. 인텔 메뉴얼에 보면 SYSENTER_EIP_MSR 가 가르키는 위치를 eip 레지스터에 넣어 실행 한다고 나와 있는데, 이 값은 MSRs(MODEL-SPECIFIC REGISTERS) 의 0x176 주소에서 가져온다. MSRs 는 rdmsr 명령으로 읽어올 수 있다.

 

IDT ( Interrupt Descriptor Table ) : 프로세서에서 인터럽트 혹은 exception  걸렸을 경우에 수행해야할 핸들러의 주소를 저장해 놓은것을 인터럽트 혹은 excetpion vector 라고 한다인텔 프로세서에서는 이러한 인터럽트 혹은 eception 핸들러들의 벡터와 벡터의 정보등을 저장해두는 구조체를 IDT 라고 부른다.

 

IDTR : 펜티엄에는 IDTR 이라 불리우는 특별한 레지스터가 존재한다 레지스터는 시스템의 IDT 존재하는 메모리 주소의베이스 어드레스와

IDT entry 의 개수가 저장되기로 약속된 레지스터 이다.

 

CPU 코어마다 IDTR 해당 IDTR 가리키는 IDT table   개수만큼 존재한다.

예를 들어 듀얼코어라면 IDTR 2개가 되고 IDT Table  두개가 된다그래서 보통 CPU 개수를 구해서 모든 IDT 조작하는 방식을 사용한다.

__asm sidt var : 해당 명령어를통해 var 변수에 IDT Entry[0] 번째 값이 들어간다.

__asm cli : 인텁트 발생 불가상태

__asm sti : 인터럽트 발생 가능 상태

 

rwlock_init : thread lock  읽고   있음

 

Kernel_thread  : 예전에 2.4.* 커널에서는 kernel_thread 함수을 직접 이용해서 thread 를 생성하고 스레드를 종료시킬때 complete을 이용해서 스레드 함수가 완전해 종료될때 까지 기다렸다가 모듈을 종료하였는데 2.6 의 현재 최신커널에서는 kthread을 사용하여 해서 위의 작업을 하는 함수가 만들어져 있다.

 

proc_dir_entry : 프로세스 디렉토리 속성값을 가지고 있는 커널 구조체

User_path_walk : it get the filename passed as argument and retrive the inode informations.. :)

lookup_dentry() : 파일 경로명을 가져온다그리고 엔트리 값을 반환한다.

GFP_KERNEL option으로 호출하면, kmalloc 당장은 메모리가 모잘라도 메모리가 생길 때까지 계속 try하는 반면에...

GFP_USER option으로 호출하면메모리 부족하면 대충 fail 끝나버리는 차이를 말하는 듯합니다.

inet_add_protocol() : 프로토콜 모듈 추가

 

nf_register_hook() 함수 : netfilter 후킹할때 사용하는데정확한 사전적 용어는 못찾음

 

init_mm은 mm_struct 라는 구조체로 이루어져 있는데 다음과 같다. 

mm_struct

위의 mm_struct 의 주석내용을 보면 다음과 같습니다. 

"owner"는 지금 mm struct의 user/owner인 정규(canonical) task를 가르켜야 한다.

init_task는 다음과 같다. 

 따라서 만약에 owner  바뀌기 위해서는 다음과 같은 과정이 행해져야 한다. 

현재 task  == mm->owner

현재 task의 mm != mm

새로운 task->mm = mm

새로운 task->alloc_lock 이 잠겨있어야 owner가 바뀔 수 있다.


'C,C++ > C' 카테고리의 다른 글

[ attribute 관련 속성 정리 ]  (0) 2014.07.02
LINUX dlopen 으로 dynamic 하게 library 호출  (0) 2014.04.24
Posted by k1rha
2014. 4. 24. 21:07

ASLR 걸린 취약한 함수 테스트 하려다가 자주 쓰게 되는데 저장할 공간이 없어서 저장함


KEYWORD : LINUX dynamic 하게 library 호출 , 라이브러리 동적 호출, 동적으로 라이브러리 호출 , dlopen dlsym dlfcn.h ..


root@k1rh4:~/strcp# ls

strcpy2.c  test.c

root@k1rh4:~/strcp# gcc -g -c -fPIC strcpy2.c

root@k1rh4:~/strcp# ls

strcpy2.c  strcpy2.o  test.c

root@k1rh4:~/strcp# gcc -shared -lc -o libstrcpy2_so.so strcpy2.o

root@k1rh4:~/strcp# ls

libstrcpy2_so.so  strcpy2.c  strcpy2.o  test.c

root@k1rh4:~/strcp# gcc -o test test.c -ldl

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

root@k1rh4:~/strcp# cat test.c

#include<stdio.h>

#include<dlfcn.h>

#include<string.h>



int main(int argc, char *argv[]){


        char buff[100]="";


        void * lib_handle=NULL;

        int (*func)(char *, char *);


        func =NULL;


        lib_handle = dlopen("./libstrcpy2_so.so",RTLD_NOW);



        if(!lib_handle){

                printf("dlopen failed [ %s ] \n",dlerror());


                return 0;


        }



        func = dlsym(lib_handle,"strcpy2");

        func(buff,argv[1]);


        printf("[%s]\n\n",buff);


        if(!func){


                printf("dsym failed [%s ] \n ", dlerror());

        }

        dlclose(lib_handle);





return 0;

}

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

root@k1rh4:~/strcp# cat strcpy2.c

#include<stdio.h>

#include<string.h>

int strcpy2(char *v1 ,char *v2){


        strcpy(v1, v2);

return  strlen(v2);

}


root@k1rh4:~/strcp#



* 공유 라이브러리 작성 컴파일 지식

gcc -fPIC -c <sorce file>
-fPIC : 위치와 관계없이 수행할 수 있는 코드로 컴파일

gcc -shared -Wl,-soname,appsolute.so.0 -o libapplib.so.0.0.0 <object files>
-shared : 공유 라이브러리로 생성
-Wl : 콤마로 구분된 옵션을 링커로 전달
-soname : 로더가 식별하는 라이브러리 이름
-o : 결과로 만들 파일이름

여기서 로더가 인식하는 이름과 실제 파일이름이 다를 수 있다.
그리고 여기서 만들고자 하는 링킹 형태는 다음과 같다.
gcc -o test test.cc -L<library path> -lappsolute
이에 심볼릭 링크를 생성하여 링커에게 이름과 실제 파일을 연결시킨다.

# 컴파일 시 -lappsolute 를 주면 링커는 libappsolute.so 를 찾는다. 따라서 libappsolute.so 를 생성한다
ln -s libapplib.so.0.0.0 libappsolute.so
# 컴파일 후 실행 파일을 실행할 경우 appsolute.so.<Version> 을 탐색한다
ln -s libapplib.so.0.0.0 appsolute.so.0
해당 링크를 추가한 후 아래 파일을 수정하여 라이브러리 경로를 추가한다.
/etc/ld.so.conf
경로 추가 후 적용
ldconfig


'C,C++ > C' 카테고리의 다른 글

[ attribute 관련 속성 정리 ]  (0) 2014.07.02
[ kernel ] 루트킷 분석하다가 조사한 커널 함수들.  (0) 2014.05.02
Posted by k1rha
2013. 3. 19. 23:15


#gcc -o pthread pthread.c -lpthread



#include <unistd.h> 

#include <stdio.h> 

#include <stdlib.h>

#include <pthread.h> 


#define THREADS 3


__thread int tls;


int global;


void *func(void *arg){

int num=(int)arg;

tls = num;

global =(int) num;

sleep(1);

printf("Thread=%d tls=%d global=%d\n",num,tls,global);

}


int main(){


int ret;

pthread_t thread[THREADS];

int num;


for(num=0;num<THREADS;num++){

ret=pthread_create(&thread[num],NULL,&func,(void *)num);

if(ret){

printf("error pthread_create\n");

exit(1);

}

}

for (num=0;num<THREADS;num++){

ret=pthread_join(thread[num],NULL);

if(ret){

printf("error pthread_join\n");

}

}


return 0;

}

Posted by k1rha
2012. 11. 28. 05:25

[출처 :http://tran.kr/94 ] 

맨날 직접 짜다보면 빠트리는 구문이 생겨버리는 구절.. 아예 가지고 있어야 겠다.



  1: #include <stdio.h>
  2: #include <string.h>
  3: #include <stdlib.h>
  4: #include <unistd.h>
  5: 
  6: int main(int argc, char **argv)
  7: {
  8:    char  optstring[1024];
  9:    extern char *optarg;
 10:    int   optchar;
 11:    
 12:    
 13:    memset(optstring, 0x00, sizeof(optstring));
 14:    
 15:    sprintf(optstring, "%s", "d:h:");
 16:    
 17:    while((optchar = getopt(argc, argv, optstring)) != EOF)
 18:    {
 19:       
 20:       switch(optchar)
 21:       {
 22:          case 'd':
 23:             printf("option d = [%s] \n", optarg);
 24:             break;
 25:          
 26:          case 'h':
 27:             printf("option h = [%s] \n", optarg);
 28:             break;
 29:             
 30:          default :
 31:             break;
 32:       }
 33:    }
 34:    
 35:    printf("End\n");
 36:    
 37:    return 0;
 38: }

Posted by k1rha
2012. 8. 20. 02:08

정말 많은 시간을 찾은듯... 이렇게 잘나와 있을 줄은 몰랐음.

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

[출처 http://zetcode.com/tutorials/mysqlcapitutorial/

Inserting images into MySQL database


Some people prefer to put their images into the database, some prefer to keep them on the file system for their applications. Technical difficulties arise when we work with millions of images. Images are binary data. MySQL database has a special data type to store binary data called BLOB (Binary Large Object).

mysql> describe images;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| id    | int(11)    | NO   | PRI |         |       |
| data  | mediumblob | YES  |     | NULL    |       |
+-------+------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

This is the table, that we will use in our example. It can be created by the following SQL statement.

create table images(id int not null primary key, data mediumblob);
#include <my_global.h>
#include <mysql.h>

int main(int argc, char **argv)
{
  MYSQL *conn;

  int len, size;
  char data[1000*1024];
  char chunk[2*1000*1024+1];
  char query[1024*5000];

  FILE *fp;

  conn = mysql_init(NULL);
  mysql_real_connect(conn, "localhost", "zetcode", "passwd", "testdb", 0, NULL, 0);

  fp = fopen("image.png", "rb");
  size = fread(data, 1, 1024*1000, fp);

  mysql_real_escape_string(conn, chunk, data, size);

  char *stat = "INSERT INTO images(id, data) VALUES('1', '%s')";
  len = snprintf(query, sizeof(stat)+sizeof(chunk) , stat, chunk);

  mysql_real_query(conn, query, len);

  fclose(fp);
  mysql_close(conn);
}

In this example, we will insert one image into the images table. The image can be max 1 MB.

 fp = fopen("image.png", "rb");
 size = fread(data, 1, 1024*1000, fp);

Here we open the image and read it into the data array.

 mysql_real_escape_string(conn, chunk, data, size);

Binary data can obtain special characters, that might cause troubles in the statements. We must escape them. The mysql_real_escape_string() puts the encoded data into the chunk array. In theory, every character might be a special character. That's why the chunk array two times as big as the data array. The function also adds a terminating null character.

 
 char *stat = "INSERT INTO images(id, data) VALUES('1', '%s')";
 len = snprintf(query, sizeof(stat)+sizeof(chunk) , stat, chunk);

These two code lines prepare the MySQL query.

 mysql_real_query(conn, query, len);

Finally, we execute the query.

Selecting images from MySQL database

In the previous example, we have inserted an image into the database. In the following example, we will select the inserted image back from the database.

#include <my_global.h>
#include <mysql.h>

int main(int argc, char **argv)
{
  MYSQL *conn;
  MYSQL_RES *result;
  MYSQL_ROW row;

  unsigned long *lengths;
  FILE *fp;

  conn = mysql_init(NULL);
  mysql_real_connect(conn, "localhost", "zetcode", "passwd", "testdb", 0, NULL, 0);

  fp = fopen("image.png", "wb");

  mysql_query(conn, "SELECT data FROM images WHERE id=1");
  result = mysql_store_result(conn);

  row = mysql_fetch_row(result);
  lengths = mysql_fetch_lengths(result);

  fwrite(row[0], lengths[0], 1, fp);
  mysql_free_result(result);

  fclose(fp);
  mysql_close(conn);
}

In this example, we will create an image file from the database.

 fp = fopen("image.png", "wb");

We open a file for writing.

 mysql_query(conn, "SELECT data FROM images WHERE id=1");

We select an image with id 1.

 row = mysql_fetch_row(result);

The row contains raw data.

 lengths = mysql_fetch_lengths(result);

We get the length of the image.

 fwrite(row[0], lengths[0], 1, fp);

We create the image file using the fwrite() standard function call.

Posted by k1rha
2012. 8. 19. 03:52

char * buff = const_cast<char *>(test.c_str());


의 형태로 c_str() 를 통해 변환이 가능하다.


Posted by k1rha
2012. 8. 19. 02:51

jsoncpp 를 다운받아서 libsjon 을 빌더한다.

그러면 라이브러리가 생겨난다. 그걸 프로젝트에 적당한 곳에 복사하고 라이브러리 디렉토리 경로로 등록해준다. 


그리고 아래와같이 json 폴더도 적당히 복사해와서 헤더로 링크 걸어주면된다.


그렇필요 가 없다는 것을 찾았다.


아래그림을 보게되는데 JOSNCPP 의 구성방식이다.

우리는 JSON 폴더만 살포시 자신의 프로젝트 폴더로 가져와서 include 시켜주면 바로 사용이 가능하다.


참간단한건데 의외로 엄청난 삽질을 햇다. 



사용은 json에 있는 json.h를 include해서 사용한다.

  1. #include <json/json.h>

 

json.h

  1. #include "autolink.h" -> config.h
    #include "value.h" -> forwards.h
    #include "reader.h" -> features.h , value.h
    #include "writer.h" -> value.h
    #include "features.h" -> forwards.h






그리고 간혹 JSONCPP 라이브러리 충돌이 난다는 메시지가 뜰대가 있는데 필자는 이걸로 엄청난 시간을 삽질했다.


http://stackoverflow.com/questions/4917592/compiling-and-using-jsoncpp-on-visual-studio10-with-boost


결국엔 스택오버플로우사이트에서 해답을 찾앗다.

  • Multithreaded (/MT)
  • Multithreaded DLL (/MD)
  • Multithreaded Debug (/MTd)
  • Multithreaded Debug DLL (/MDd)

디버깅모드는 위와같이 4가지가 있는데 JSON 라이브러리는 활성 모드와 디버그 모드가 동일하게 디버깅 모드가 동작하고 있어야 하며 JSON 라이브러리에서는  /MT 시리즈를 선호한다.





Posted by k1rha
2012. 8. 17. 10:53


ILedService.h


서버1.cpp


서버2.cpp


클라이언트1.cpp


클라이언트2.cpp


클라이언트3.cpp


위파일들은 헤더를 기준으로 서버1 -> 에서 좀더 객체지향적인 서버 2가 완성되었고

클라이언트도 1-> 2 -> 3 순서로 수정되어 같은 역할을 하는 것을 좀더 OCL 에 맞추어 개발하는 방향이다.

완성코드는 아래와 같다.


========================================== [ Server ]=================================================


#include<Windows.h>

#include<iostream>

#include<conio.h>


using namespace std;

void binder_loop(void (*handler)(int,int ,int))

{


//여기서 바인더 드라이버를 Open 해서 Client 에서 오는 event를 대기합니다.

//우리는 윈도우 메세지로 흉내 내도록 하겟습니다.

while(1)

{

MSG msg;

GetMessage(&msg,0,0,0);

handler(msg.message,msg.wParam,msg.lParam);


}

}


//---------------------------------------------------------

void Ontransact(int code, int param1, int param2)

{

switch(code)

{

case 5: cout << "LED ON" <<endl; break;

case 6: cout << "LED OFF" << endl; break;

}

}


DWORD __stdcall ServerMain(void *)

{

cout << "서버시작"<< endl;

binder_loop(Ontransact);

return 0;


}

================================== [ Client ] ===================================================

#include<Windows.h>

#include<iostream>

#include<conio.h>

#include "ILedService.h"


using namespace std;


DWORD ServerID=0;


DWORD __stdcall ServerMain(void *);

//---------------------------------------------------------------

//안드로이드가 제공해주느 함수 부분

void binder_call(int code, int param1, int param2)

{


PostThreadMessage(ServerID,code,param1,param2);


}


class IBinder

{

public:

void transact(int code, int param1, int param2){

binder_call(code,param1, param2);


}

};

//서비스 이름을 인자로 받아서 해당 서비스와 통신하기 위한 바인더를 만들어주는 

//함수


IBinder * getService(char *name )

{

//드라이버를 오픈해서 통신할 수 있는 바인더를 만들어 리턴

return new IBinder;

}

class BpRefBase

{

private :

IBinder *mRemote;

public :


BpRefBase(IBinder *p) : mRemote(p) {}

IBinder * remote() { return mRemote;}


};

//proxy 제작시 - 다중 상속을 단일 상속화 한다.

template<typename INTERFACE>

class BpInterface : public INTERFACE ,public BpRefBase

{

public :

BpInterface(IBinder *p) : BpRefBase(p){} //주의!

};


template<typename INTERFACE> INTERFACE * interface_cast(IBinder *p){

return INTERFACE::asInterface(p);


}


//--------------------안드로이드 제공소스 끝 ---------------------------------

// 이제 바인더를 바로 사용하지 말고 함수 호출처럼 변경하는 클래스를 제공합니다

//

//Proxy : 함수 호출 -> RPC 코드 변경 하는 역할.

//

class BpLedService : public BpInterface<ILedService>

{

public :


BpLedService(IBinder * p) : BpInterface<ILedService>(p){}


//////////////////////////////////////////////////////////

// void LedOn(){remote()->transact(5,0,0);}

// void LedOff(){remote()->transact(6,0,0);}

// 위의 경우는 어느게 ledOn인자 LedOFF인지 숫자를 외워야한다...

// 때문에 pLed를 만든다

//////////////////////////////////////////////////////////

void LedOn(){remote()->transact(5,0,0);}

void LedOff(){remote()->transact(6,0,0);}

};


//이제 proxy 제작자는 proxy 클래스를 제공한후 반드시 asInterface 구현부를 

// 제공하기로 약속 한다.

//

ILedService * ILedService ::asInterface(IBinder *svc){

return new BpLedService(svc);

}

void ClientMain(){


IBinder * svc = getService("LedService");

//이제 바인더를 바로 사용하지 말고 __ 로 변경해서 사용합니다.

//BpLedService *pLed = new BpLedService(svc); //강한 결합

//ILedService * pLed = ILedService::asInterface(svc);//약한 결합


ILedService * pLed = interface_cast<ILedService>(svc); // 약한결합을 간지나게 바꿈 

//바인더를받아 스테틱 캐스팅느낌으로...(사실은 프락시)



while(1)

{

// getch(); svc->transact(5,0,0);

// getch(); svc->transact(6,0,0);

getch(); pLed->LedOn();

getch(); pLed->LedOff();

}


}


int main()

{

CreateThread(0,0,ServerMain,0,0,&ServerID);

Sleep(1000);

ClientMain();

getch();

}




Posted by k1rha
2012. 8. 16. 17:46

#include<iostream>


using namespace std;



///////////////////////////////////////////////////////////////////

// perfect forwarding (완벽한 전달자 문제)

////////////////////////////////////////////////////////////////////


void foo(int &a){

a+=10;

cout << "foo" << endl;

}

void goo(int a){cout << "GOO " << endl;}



//함수를 호출해주는 도구 - 바인더가 결국 함수를 가지고 있다고 다시 호출해

// 주는 것입니다.

//

template<typename F, typename ARG> void Caller(F f,const ARG &a)  //함수도 전달되고 상수도 전달되는 퍼팩트 포워딩법

{


f(a);

}


int main(){

//goo(10);

Caller(goo,10);

}


/*

int main(){

int a= 10;

//foo(a);

Caller(foo,a);

cout << a <<endl;

}


*/








Posted by k1rha
2012. 8. 16. 14:57

#include<iostream>


using namespace std;


///////////////////////////////////////////////////////////////////////////////////////////////////////////

// traits 이야기

// 1.Traints : T의 특질(특성)을 조사하는 기술 ...(template 에서 특성에 따라 받아들임이 다름을 이용하는 기술

// primary template 에서 false 를 리턴 (enum 상수가 false)

//

//////////////////////////////////////////////////////////////////////////////////////////////////////////

//


template<typename T> struct my_is_array

{

enum {size=-1}; 

enum {value = false};

};

template<typename T,int N> struct my_is_array<T [N]>

{

enum {size =N};

enum {value =true};

};

template<typename T> void foo(const T& a)

{

if(my_is_array<T>::value)

cout<<"배열 입니다" << my_is_array<T>::size <<endl;

else

cout<<"배열이 아닙니다" << endl;


}

/*

template<typename T>struct my_is_pointer

{

enum{ value = false};

};

template<typename T>struct my_is_pointer<T*>

{

enum{ value = true};

};


template<typename T>void foo(const T& a)

{

if(my_is_pointer<T>::value)

cout<< "T는 포인터 입니다"<<endl;

else

cout<<"T는 포인터가 아닙니다." << endl;


}


*/

/*

template<typename T> T Max(T a, T b)

{

//return 은 주소 비교를 할수 없기때문에.. 좀더 if 문을 넣어 똑똑하게 만들자

if(T is Pointer)

return *a < *b ? b : a;

return a< b ? b : a;


}

*/


int main()

{

//int x = 10, y = 20;

/*

Max(x,y);

Max(&x, &y);

*/


int x = 0;

int y[19];

foo(x);

foo(y);


}

Posted by k1rha
2012. 8. 16. 11:47

#include<iostream>

using namespace std;


///////////////////////////////////////////////////////////////////////////////////////

// 클래스 템플릿의 멤버 함수 템플릿이 사용되는 대표적인 경우

// 1. complex 를 템플릿으로 설계하는 이유 

// 2. T a = T(); => zero initialize : T 가 포인터 또는 빌트인 타입이면 0

// User 타입이면 디폴트 생성자로 초기화

//

//

////////////////////////////////////////////////////////////////////////////////////////


template<typename T>class complex{


T real;

T image;


public:

complex(int a =T() , int b=T()) : real(a), image(b){}

//  Template 복사 생성자!!

// "U 가 T로 복사 될수 있을때 complex<U> 는 complex<T>로 복사 될 수 있어야 한다.

///

template<typename U>complex(const complex<U> & c) : real(c.real), image(c.image)

{


}

template<typename > friend class complex;

};


int main(){

// so <Dog> p1 = new Dog;

// sp <Animal> p2 = p1;  //template 복사 생성자가 있어야 한다.

//  



complex<int> c1(1 , 2);

complex<int> c2 = c1; //복사 생성자!! 

complex<double> c3= c1;



}

Posted by k1rha
2012. 8. 16. 11:45

#include<iostream>


using namespace std;


// 1. stack Vs stack<T>

//


template <typename T> class Stack

{


public : 

// 다음중 생성자로 맞는것은?

Stack() {} //1

Stack() { } //2


//다음중 복사 생성자로 맞는 것은? 


Stack(const Stack &s){} //1  클래스 안에서는 이 표현도 허용된다.

Stack(const Stack<T>& s){} // 2 OK 정확한 표현?! 


//멤버 함수의 외부 구현

void push(const T& a);

//클래스 템플릿의 멤버 변수  함수 템플릿


template<typename U> T foo(U a);

};

template<typename T >void Stack<T>::push(const T& a){

}


template <typename T> template<typename U> stack<T>::foo (U a){}


int main(){


//Stack s1;  //error Stack 은 타입이 아니라 template 이다.

Stack<int> s2;  // OK stack<int> 는 타입이다.


}

Posted by k1rha
2012. 8. 16. 11:44

#include<iostream>

using namespace std;

///////////////////////////////////////////////////////////////////////////////////////

//함수 템플릿 이야기

// 함수 인자 값으로 받으면 : 배열 -> 포인터  함수-> 함수 포인터로 변경하여 전달된다. 

// 이러한 현상을 Decay 라고 부른다.

///////////////////////////////////////////////////////////////////////////////////////


/*

template<typename T>void foo(T a){

//template<typename T>void foo(T& a){ //참조로 받으면 정확한 타입이 넘어온다

//참조냐? 값이냐에 따라 달라진다.


//template 에서는 가상함수가 없어도 빌트인 타입이 없어도 typeid()사용이 가능합니다.

cout << typeid(a).name() << endl;


}


int main(){

int n =10;

int x[10];


foo(n); // T-> int

foo(x);  // int *

foo("apple"); // const char *

foo(main); //int (*)()


}

*/



template<typename T> void foo(const T& a, const T& b)

//template<typename T> void foo(const T a, const T b)

{


}


///아래와 같이 따로 받는것이 나을수도 있따.

void foo(const char *s1, const char * s2)

{

}


int main()

{

foo("orange","apple"); // 함수 찾는 순서

//1. 정확한 타입이 있으면 찾는다

//2. 변환 가능 타입이 있으면 찾는다.

//3. template 버전을 사용한다.


}



Posted by k1rha
2012. 8. 16. 10:55

#include<iostream>


using namespace std;

///////////////////////////////////////////////////////////////////////////////////////

//RTTI 를 직접 구현해보자.

//결국 type_info 는 클래스당 1개의 static 멤버 data 이다.

//type_info 역할의 클래스를 설계하자.

////////////////////////////////////////////////////////////////////////////////////////


struct CRuntimeClass

{

string name; //클래스 이름을 관리


};


// 이제 아래처럼 약속하자! (RTTI 를 직접 구현해보자!!) 

//1.  모든 클래스에는 CRuntimeClass 가 정적 멤버로 있어야 한다.

//2.  이름은 "class클래스 이름 " 으로 약속하자.

//3.  정적 멤버를 리턴하는 가상함수 GetRuntimeClass()를 만들기로 하자.

//


class CObject 

{

public:

static CRuntimeClass classCObject;

virtual CRuntimeClass * GetRuntimeClass() { return &classCObject;}


};

CRuntimeClass CObject::classCObject = {"CObject"};


class CWnd : public CObject{


public :

static CRuntimeClass classCWnd;

virtual CRuntimeClass * GetRuntimeClass() { return &classCWnd;}


};


///////////////////////////////////////////////////////////////

// 여기부분에서 virtual 이므로 재정의 하게 된다

// CObject 타입에 CWnd 를 넣으면 vitual table 의 포인터를 동적으로 참조하므로

// CWnd 함수로 된 것이 호출된다. 이로써 CObject 를 오버라이딩한듯한 효과를 이룬다.

//////////////////////////////////////////////////////////////

CRuntimeClass CWnd::classCWnd = {"CWnd"};


void foo(CObject *p){

// p 가 CWnd 인지 조사해보세요

//

if(p->GetRuntimeClass()== &CWnd::classCWnd )

{

cout << " p 는 CWnd 입니다 " <<endl;

}

}

int main(){


CWnd w; 

foo(&w);

}



////////////////////////////////////////////////////////////////////////////////


Posted by k1rha
2012. 8. 16. 10:54

#include<iostream>


using namespace std;


//////////////////////////////////////////////////////////////////////

// RTTI 이야기

// 1. 가상함수 테이블로 관리되는 type_info 를 얻어서 조사한다.

// 2. typeid(*p) == typeid(Dog) 로 조사한다.

// 3. Dog *p1 = dynamic_cast<Dog *>(p); C# Dog p1 = p as Dog;

//

//

/////////////////////////////////////////////////////////////////////

/*

class Animal{


public:

virtual ~Animal(){}

};


class Dog : public Animal

{


};


void foo(Animal *p) // 모든 동물이 전달 될 수 있다.

{

//ㄹ/결국 아래 코드 표현을 사용하면됩니다.

if(typeid(*p) == typeid(Dog)){

}



 //모든 동물에 공통된 일을 하겠습니다.

 // 그런데 혹시 P가 Dog 라면 다른 일도 하고싶다!

 //P가 Dog 인지 알고싶다 - Run Time Type Information : RTTI 

 //

 //가상 함수 테이블로 관리되는 type_info를 얻어낸다.

const type_info& t1 = typeid(*p);  //typeid (객체)

const type_info &t2 = typeid(Dog); //typeid(클래스 이름)

cout  << t1.name() << endl;


if(t1==t2){

cout << " p는 Dog 입니다."<<endl;


}

cout << t1.name()<<endl;


}


int main(){


Animal a; foo(&a);

Dog d; foo(&d);


}

*/




class Animal{


public:

virtual ~Animal(){}

};


class Dog : public Animal

{


};

void foo(Animal *p){

//Dog *p1 = static_cast <Dog *> (p); //Down cast (부모를 자식포인터로 캐스팅) 을 조사못한다.


//Dog *p1 = dynamic_cast<Dog *>(p); //Down cast 발생시 0이 된다.



cout << p1 << endl;

}

int main(){

Animal a; foo(&a);

Dog b; foo(&d);

}


Posted by k1rha
2012. 8. 16. 09:58

#include<iostream>


using namespace std;;



///////////////////////////////////////////////////////////////

// 가상 소멸자 이야기

// 1. 결론 : 모든 부모의 소멸자는 반드시 가상이어야 한다.

// 어제배운 모든 인터페이스(Ivalidator 등) dp qksemtl rktkd thaufwkfmf cnrkgodigksek.

// 

//////////////////////////////////////////////////////////////

/*

//1.

class Base{

//아래와 같은 문제를 해결하기 위해서 소멸자를 넣어야한다.

//virtual ~Base(){}

};


class Derived : public Base{


public:

Derived() { cout<< " 메모리 할당 " << endl;}

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


};


int main(){


Base *p = new Derived;

delete p;  //type 이 Base 이기 떄문에 소멸자가 가상함수가 아니라면 P의  타입만 가지고 소멸자 호출.

// 결정한다. static binding.



}

*/


//실행해보세요



/*

//12.

class Base{

//아래와 같은 문제를 해결하기 위해서 소멸자를 넣어야한다.

//virtual ~Base(){}

protected:

~Base{} // 가상 소멸자의 오버헤드를 없애는 기술

//부모 타입으로는 절대 delete 하지말라는 철학.


};


class Derived : public Base{


public:

Derived() { cout<< " 메모리 할당 " << endl;}

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


};


int main(){


Base *p = new Derived;

delete p;  //type 이 Base 이기 떄문에 소멸자가 가상함수가 아니라면 P의  타입만 가지고 소멸자 호출.

// 결정한다. static binding.


delete static_cast<Derived *>(p);


}

*/


Posted by k1rha
2012. 8. 16. 09:56

#include <iostream>

using namespace std;

/*

class Base

{

int a;


public: inline virtual void foo(){}

virtual void goo(){}

virtual void hoo(){}


};


class Derived : public Base{

int b;

public : 

virtual void foo(){}

};

int main(){


Base b; cout << sizeof(b)<<endl;

Derived d; cout << sizeof(d)<<endl;  

//////////////////////////////////////////////////////////

/// 가상함수 테이블로 인해 4바이트가 늘어난다.

///////////////////////////////////////////////////////////


Base *p = &d;

p->foo();  //*p 가 가르키는 곳을 따라가면 .. goo가 있을 것이다.. 그중에 첫번째 를 호출해 달라.. *p[1]()

//가상 함수의 장점 : 실행 시간 다형성을 얻을 수 있다.

// 단점  : (1) 가상함수 테이블 때문에 메모리 부담. MFC가 이 부담을 없애기 위해 메세지 맵 도입

// (2) 실제 객체의 크기보다 4바이트 더 필요하다. - 약간의 메모리 부담

// (3) 함수 호출시 간접 호출에 따른 속도의 부담

// (4) 인라인 치환이 불가능해서 성능의 부담..

//

// 



}*/

////////////////////////////////////////////////////////////////////////////////


#include<iostream>

using namespace std;


/////////////////////////////////////////////////////////

// 가상함수 이야기 2 

// 가상함수는 실행시간에 어느 함수인지가 결정된다.

// 디폴트 인자는 : 컴파일러가 한다.

// 가상함수에서는 되도록이면 디폴트 인자를 사용하지 말자!.

//

//////////////////////////////////////////////////////////

/*

class A{

int x;

public :

virtual void foo(){ cout << "1" << endl;}

};


class B{

int y;

public:

virtual void goo(){ cout<< "2"<<endl;}

};


int main(){


A a;

B* p = reinterpret_cast<B*>(&a); 

p->goo();


//////////////////////////////////////////////////////////////

//A와 B에 virtual 을 넣었을때와 뺏을떄의 결과값이 다르다.. 왜?!

// 가상함수는 포인터의 개념이기 떄문에, 

// 가상함수가 없을떄는 static binding 을 통해 메모리가 정해지지만

// 가상함수를 넣어줌으로써 dynamic binding 을 통해 상대적으로 가르치고 있는곳을 가르킨다.

////////////////////////////////////////////////////////////////////


}*/

/*

class A{

public :

virtual void foo(int a=10){cout << "1: "<< a<<endl;}

};

class B : public A{  // 이번엔 상속을 봐보자.

public :

virtual void foo(int a=20){cout << "2: "<< a<< endl;}

};

int main(){


A *p = new B;

p->foo(); //실행하지 말고 결과 예측?!

//2 : 10  이나온다..ㅠㅠ 

//컴파일시에는 a가 초기화 되고 , 실행시는 함수포인터가 결정된다

//즉 결과는 *p[1](10) 이 나온다.

}

*/

//////////////////////////////////////////////////////////////////////////////////////////////////

Posted by k1rha
2012. 8. 15. 17:54

#include<iostream>

#include<functional>

using namespace std;

using namespace std::placeholders;



//Dialog 복사해오세요


void foo(int a) { cout << "foo" << a<< endl;}

void goo(int a, int b, int c){ cout<<"goo"<< a<<b<<c <<endl;}


//범용적 함수 포인터 - function

//

class Dialog{

public : 

void Close(){cout<<"Dialog.. Close"<<endl;}

};

int main(){



function<void(int)> f = &foo;

f(1);

//f = &goo; //3개의 이자값을 1개로 대입할수 없다

f = bind(&goo,1,_1,9);

f(3);


function<void()> f2 = bind(&foo,5);

f2();


Dialog dlg;

f2=bind(&Dialog::Close,&dlg);

f2();


}


Posted by k1rha
2012. 8. 15. 15:56

#include<iostream>

using namespace std;


////////////////////////////////////////////////////////////////////////////////////////

// 추상클래 스이야기

// 순수 가상함수가 1개 이상인 클래스

// 강제로 자식에서 특정 함수를 만들라고 지시하는 것!!! 

//

//

////////////////////////////////////////////////////////////////////////////////////////




class Shape{


public : 

virtual void Draw() = 0; //순수 가상함수  구현이 없다.

};

class Rect : public Shape  //Draw()의 구현을 제공하지 않았으므로 추상 클래스 이다.

{


};

int main(){

Shape s; //구현부가 없으므로 에러가 뜬다 // 추상클래스는 객체를 만들 수 없다.

Rect r;  // 에러가 뜬다 사용하고 싶다면 draw()를 만들어야 한다!

}


=========================================================================================

인터페이스의 탄생배경

========================================================================================

#include<iostream>

using namespace std;


// 강한결합 (tightly coupling) : 하나의 클래스 다른 클래스의 이름을 직접 사용 하는것...

// //교체 불가능 경직된 디자인

//스마트폰 제조사와 사람사이ㅔ서의 계약서 (규칙, 인터페이스)를 만들자!

// 모든 스마트폰은 아래 클래스의 자식으로 만들어야 한다.

//

// 약한 결함 (loosly coupling) : 하나의 클래스가 다른 클래스를 사용할떄  부모인 추상클래스를 사용하는 

// //접근법! 교체가능한 설계, 유연한 디자인의 핵심!! 


#define interface struct 

interface ISmartPhone{

public : 

virtual void Calling(char *no) = 0;

//더욱이 인터페이스는 한가지 일만하는게 좋다. 모든 스마트폰의 엠피3기능이 있는것은 아니므로 여러개의 interface를 구현하는게 맞다.

}

interface Mp3function{

public : 

virtual void music(char *no) = 0;

//더욱이 인터페이스는 한가지 일만하는게 좋다. 모든 스마트폰의 엠피3기능이 있는것은 아니므로 여러개의 interface를 구현하는게 맞다.

}



//규칙이 있으므로 진짜 스마트폰이 없어도 사용하는 코드를 먼저 만들 수 있다.

//규칙대로만 사용하면 된다!! 

//


class People{


public :

void UsePhone( ISmartPhone * p ) { p->Calling("010-111-2222");}


};


//이제 모든 스마트폰은 ISmartPhone의 자식이라는 규칙만 지키면된다.




//상송이란 개념을 물려받는 개념... 

//때문에  인터페이스의 경우는   인터페이스를 구현해야 한다 라고 표현한다.

class GallexyS : public ISmartPhone{


public :

void Calling(char *no) { cout << "Calling with GallexyS" << endl;}


};


class GallexyS2: public ISmartPhone, public Mp3function{ //s2는 음악까지됨 


public :

void Calling(char *no) { cout << "Calling with GallexyS2" << endl;}


};

/*


class People{


public :

void UsePhone(GallexyS *p){p->Calling("010-9179-3197");}

void UsePhone(GallexyS2 *p){p->Calling("010-9179-3192");}

};

*/


int main(){


People p;

GallexyS s;

p.UsePhone(&s);

GallexyS2 s2;

p.UsePhone(&s2);


}

*/

Posted by k1rha
2012. 8. 15. 13:28

#include<iostream>

//using namespace std;


//////////////////////////////////////////////////////////////////////

//  접근 변경자!

//////////////////////////////////////////////////////////////////////

// 1. 부모의 멤버를 물려 받을때 접근 지정자를 변경해서 물려 받게 하는 기술

//////////////////////////////////////////////////////////////////////


/*

class A {


private: int a;

protected: int b;

public: int c;



};

class B : public A{


};

int main(){

A a;

B b;

a.c = 10;

b.c = 10;


}

*/


#include<list>

//////////////////////////////////////////////////////////////////////////////////////////////////////

//list 가 있다. 

//그런데 스텍이 필요하다!

// 그럼 새롭게 만드는것보다 list를 한방향으로만 사용하면 stack 이다..list를 재사용하자

// LIST 클래스를 다른 클래스 stack 처럼 사용한다

//

//어댑터 패턴 : 기존 클래스의 인터페이스(함수 이름)을 변경해서 다른 클래스처럼 보이게 하는 디자인 기술.

//

//이럴때 list의 있는 함수는 쓰기 싫지만, 자신은 써야할떄 private 상속을 하면됨.

//private 상속 철학: 구현은 물려 받지만 (자식이 내부적으로 사용하지만 인터페이스는 물려받지 않겠다 : 

// :부모함수를 노출하지는 않겠다.

//////////////////////////////////////////////////////////////////////////////////////////////////////

/*

using namespace std;


template<typename T> class stack : private list<T>{

public:

void push(const T &a) {push_back(a);}

void pop() {pop_back();}

T & top() {return back();}


};


int main(){

stack<int> s;

s.push(10);

cout << s.top()<<endl;


}

*/

/*

/////////////////////////////////////////////////////////////////////

//s/w 재사용에는 상속 뿐만 아니라 포함도 있다.

//int 형외에 벡터도 가져오고 싶은데 

// 사용자편의를 위해서 디폴트를 int형으로 선언하고싶다! 

//아래와같이 코딩함

/////////////////////////////////////////////////////////////////////

using namespace std;

template<typename T,typename C=deque<int>> class stack{

C st;

public:

void push(const T&a) {st.push_back(a);}

void pop() {st.pop_back();}

T & top() {return st.back();}

};

int main(){

stack<int> s;

s.push(10);

cout << s.top();


}

*/



Posted by k1rha
2012. 8. 15. 11:04

#include<iostream>

#include"memchk.h"

using namespace std;


//new를 재정의하는 다양한 기법



int main(){

int *p1 = new int;

int *p2 = new int;

int *p3 = new int;

delete p2;

/*


cout << __FILE__ << endl;

cout << __LINE__ << endl;

cout << __TIME__ << endl;

*/ //표준 C/C++ 에서 지원하는 메크로


return 0; // 다른 헤더에서 메임을 가짜로 바꿨으니.. 리턴0을 써줘야한다

}

====================================memchk.h==============================================


#include<iostream>

using namespace std;


struct MEM{


char file[256];

int line;

void * addr;

};


MEM mem[1000];

int count =0;

void * operator new (size_t sz , char *file , int line){

void *p = malloc(sz);

//할당정보를 배열에 보관한다.


mem[count].addr = p;

mem[count].line = line;

strcpy(mem[count].file, file);

++count;

return p;

}


void operator delete(void *p){


for(int i=0;i<count ; i++){

if(mem[i].addr ==p){

mem[i] = mem[count-1];

free(p);

--count;

break;

}

}

}

int Main();

int main(){

int ret = Main();  //사용자 메인함수는 단순 호출이고 그뒤에 내가 원하는 결과를 붙인다.


if(count == 0)cout << "메모리 누수가 없습니다"<<endl;

else{

cout << count << "개의 메모리 누수가 있습니다."<<endl;

for(int i=0;i<count;i++){

printf("%s(%d):%p\n",mem[i].file, mem[i].line, mem[i].addr);

}

}

return ret;

}


#define main Main   //이후에 메인은 메인이 아니다!!!  그 메인의 리턴값 이후에 무언가를 출력시킴 

#define new new(__FILE__, __LINE__)  //new를 디파인

int *p = new int;


Posted by k1rha
2012. 8. 15. 11:02

#include<iostream>


using namespace std;


/////////////////////////////////////////////////

//New 이야기

//1 New 의 동작 방식

//(A)operator new() 함수를 사용해서 메모리를 할당 한후

//(B)(A) 가 성공했고 객체 였다면 생성자 호출

//(C) 주소를 해당 타입으로 캐스팅해서 리턴.

//

//delete

//(A) 소멸자 호출

//(B) operator delete()를 사용해서 메모리 해지

//

//////////////////////////////////////////////////////////////////

class Test{


public:

Test(){cout<<"Test()"<<endl;}

~Test(){cout<<"~Test()"<<endl;}

};


int main(){

//생성자 소ㅕㄹ자의 호출없이 메모리만 할당/해지하는 방법

//결국 C의 malloc과 유사


Test *p = static_cast<Test *>(operator new( sizeof(Test));

operator delete(p);


}

=====================================================================================


Posted by k1rha
2012. 8. 14. 17:43

#include<iostream>

using namespace std;


/////////////////////////////////////////////////////////////

// 변환 이야기

// Point -> int : 변환 연산자

// int -> Point : qusghks todtjdwk (인자가 1개인 생성자)

////////////////////////////////////////////////////////////


class Point{



int x, y;


public:

Point() :x(0),y(0){}

Point(int a , int b):x(a),y(b){}


//변환 연산자 : 객체를 다른 타입으로 암시적/ 명시적 형변환 되게 한다.

// 변환 연산자는 리턴값을 표시하면 에러이다.

operator int(){


return x;

}


Point(int a) :x(0),y(0){} // 변환생성자 

};

/*

int main(){


double d = 3.4;

int n =d;


Point p(1,2);

int n2 = p; //p.operator int() 가 있으면 된다.

}

*/


int main(){

Point p1(1,2);

int n =p1; // p1.operator int() 이므로 OK 

//Point -> int 변환

// p1=n; // int -> Point 변환 

// 똑같은 의미에서 n.operator Point() 가 있으면 된다. 하지만 n 은 객체가 아니다 ㅠㅠ


p1=n; // 변환 생성자 적용 후 int 형생성자가 있으면 가능하다!

//컴파일러가 임시 객체를 만들어서 집어넣은뒤 대입연산자를 통해 넣어주게 된다.

}



================================ 활용 법 ===========================================


#include<iostream>

using namespace std;


class OFile 

{


FILE *file;


public:


//모르는 연산자가 넘어오는 것을 방지하기 위해서.. 인자가 1개인 생성자가 암시적으로 변환을 일으키는 것을 막는다.

//explicit  // 단! 명시적 변환은 된다.

explicit OFile (const char *name , const char *mode = "wt"){

file = fopen (name ,mode);

}

~OFile(){fclose(file);}


void write(const char *s){fwrite(s,1,strlen(s),file);}


//operator  // 차세대 C++ 은 변환  연산자 앞에도 explocit 를 붙일 수 있따.

operator FILE*(){return file;} // 변환 연산자?!!!


};


/////////////////////////////////////////////////////////////////////

//변환 연산자의 적절한 예시

////////////////////////////////////////////////////////////////////

/*

int main(){

OFile f("a.txt");

f.write("hellow");

int n=10;

fprintf(f,"n=%d",n); //OFILE 이 파일포인터로 변환만 될수 있따면 ..ㅠㅠ 벼..변환 연산자?!

///////////////변환 연산자 후엔 다 슬수 있다.////////////////////

fputs("world",f);



////////////////다른 예를 들어보자! ////////////////////////////////////////////

// char s[10]="hello";

// String s2="aaa";

// strcpy(s,s2); //?



}


*/

void foo(OFile f){


}

int main(){


OFile f("a.txt");

foo(f); // 당연하다!!!! 

//////////////explicit 적용전 ///////////////////////

/// foo("hellow"); //!?

//error 가 나와야한다

//잘된다!! char * -> OFile 이 면 된다! 

//////////explicit 적용후는 안됨 ///////////////////////


foo((OFile)"hellow"); //의도적으론 된다.

}

==================================================================================================

Posted by k1rha
2012. 8. 14. 16:52

#include<iostream>

#include<algorithm>


using namespace std;


///////////////////////////////////////////////////////////////////////////////

// STL 의 sort() 는 마지막 인자가 T로 되어 있다.

//

//

//

///////////////////////////////////////////////////////////////////////////////


// 아래 코드의 단점 인라인 처리가 안된다?!

/*

int cmp1(int a, int b) {return a-b;}

int cmp2(int a, int b) {return b-a;}


int main(){


int x[10] = {1,2,3,4,5,6,7,8,9,10};

sort(x,x+10,cmp1);  //sort(int *, int *, int(*)(int,int)) 함수 생성 

sort(x,x+10,cmp2); //sort(int *, int*, int(*)(int,int))




}

*/


//////////////////////////////////////////////////////////////////////////////

// 이미 있는 STL 이다!!

// #include <functional> 다있다! 다있따!  //less<> , greater<>

////////////////////////////////////////////////////////////////////////////

template<typename T>struct less{

bool operator()(T a,T b){return a<b;}

};


struct greater {bool operator()(int a, int b){return a>b;}};


int main(){


int x[10] = {1,2,3,4,5,6,7,8,9,10};

less<int> cmp1;

greater cmp2;


sort(x,x+10,cmp1); //sort(int *, int *, less) 함수 생성

sort(x,x+10,cmp2); //sort(int *, int*, greater) 함수 생성




}

=====================================================================

함수객체이야기

=====================================================================

#include<iostream>

#include<algorithm>


using namespace std;


///////////////////////////////////////////////////////////////////////////////

// STL 의 sort() 는 마지막 인자가 T로 되어 있다.

//

//

//

///////////////////////////////////////////////////////////////////////////////


// 아래 코드의 단점 인라인 처리가 안된다?!

/*

int cmp1(int a, int b) {return a-b;}

int cmp2(int a, int b) {return b-a;}


int main(){


int x[10] = {1,2,3,4,5,6,7,8,9,10};

sort(x,x+10,cmp1);  //sort(int *, int *, int(*)(int,int)) 함수 생성 

sort(x,x+10,cmp2); //sort(int *, int*, int(*)(int,int))




}

*/


//////////////////////////////////////////////////////////////////////////////

// 이미 있는 STL 이다!!

// #include <functional> 다있다! 다있따!  //less<> , greater<>

////////////////////////////////////////////////////////////////////////////

template<typename T>struct less{

bool operator()(T a,T b){return a<b;}

};


struct greater {bool operator()(int a, int b){return a>b;}};


int main(){


int x[10] = {1,2,3,4,5,6,7,8,9,10};

less<int> cmp1;

greater cmp2;


sort(x,x+10,cmp1); //sort(int *, int *, less) 함수 생성

sort(x,x+10,cmp2); //sort(int *, int*, greater) 함수 생성




}


/////////////////////////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////////////

//절대값 오름 차순시?

/////////////////////////////////////////////////////////////

template <typename T>struct absLess{

inline bool operator()(T a, T b){return abs(a) < abs(b);}


};


int main(){


int x[10] = {1,3,5,7,9,-2,4,6,8,10};

//절대값 오른차순으로 소트하고싶다.

absLess<int> cmp;

sort(x,x+10,cmp);

}

Posted by k1rha
2012. 8. 14. 15:13

#include<iostream>

using namespace std;

/////////////////////////////////////////////////////////////////////////////////

//STL 알고리즘

//guswo C++ 의 대부분의 라이브러리는 Ferneric 을 중요시 합니다 (STL 안드로이드 등) 

//

// Generic 이란 무엇인지 생각해 봅시다

//

// 1. 알고리즘 만들기

//

///////////////////////////////////////////////////////////////////////////////////


/*

//1단계 strchr() 의구현

//검색구간 : NULL 로 끝나는 문자열, ㅜㅕㅣㅣdms rjatordp vhgka dksehlsek.

//구간의 표현 : 포인터 

//구간의 이동 : 전위형 ++

//실패의 전달 : 0(NULL 포인터 )

//


char * xstrchr(char *s,char c){

while( *s !=0 && *s!=c)

++s;


return *s ==0 ? 0 : s;

}


int main(){



char s[] = "abcdefg";

char *p = xstrchr(s,'c');

cout << *p <<endl;

}



*/


/*

//////////////////////////////////////////////////////////////////////////////

//2단계 구현  일반화 - 부분 문자열도 검색이 가능하게 만드는 방법

// 검색 구간 : [fist , last) 사이의 문자열, ㅣㅁㄴㅅ sms rjatordp vhgkadksehla

// 구간의 표현 : 포인터

// 구간의 이동 : 전위형 ++

// 실패의 전달 : 0 (NULL)

//////////////////////////////////////////////////////////////////////////////

char * xstrchr(char *first, char *last , char value){

while(first !=last && *first !=value)++first;

return first == last ? 0 : first;

}

int main(){


char s[] ="abcedfg";

char * p = xstrchr(s,s+5,'c');

cout<< *p <<endl;


}

*/


/*

//////////////////////////////////////////////////////////////////////////////

//2단계 template 이용하기

//문제점 : 1 . 검색 구간의 타입과 검색 대상의 타입이 연관되어 있다.

//해결책 :  double 에 배열에서 int를 검색할 수 없다. 구간의 타입과 검색의 타입을 분리하자!

//

//문제점 : 2. T* 라고 하면 구간은 반드시 진짜 포인터로만 표현 되어야 한다.

//     스마트 포인터를 사용 할 수 없다.

//

/////////////////////////////////////////////////////////////////////////////

template <typename T> T* xfind(T *first, T* last , T value){

while(first !=last && *first !=value)++first;

return first == last ? 0 : first;

}


int main(){


double x[10] = {1,2,3,4,5,6,7,8,9};

double *p = xfind(x, x+10,5.0);

cout << *p << endl;



}

*/


////////////////////////////////////////////////////////////////////////////////

/// 검색내용과 검색부분을 분리해내자! 그렇게되면 스마트 포인터도 사용 할 수있다.

// 검색 구간 : [first, last) 모든 타입의 배열의 부분구간

// 구간의 표현 : 포인터 , 스마트 포인터(단  == , != , * , ++ 4개의 연산자 지원이 되느 스마트 포인터여야 한다.

//

//////////////////////////////////////////////////////////////////////////////

//

//실패의 전달 : last (past the end 라고 부르기도 한다. 마지막검색 다음 요소 

//////////////////////////////////////////////////////////////////////////////////////////////

//

// 이..이것슨!! STL 의 find() 알고리즘이다!!! 

//

///////////////////////////////////////////////////////////////////////////////////////////

template<typename T1, typename T2> T1 xfind(T1 first, T1 last, T2 value){


while(first !=last && *first !=value)++first;

return first;

}


int main(){


double x[10] = {1,2,3,4,5,6,7,8,9};

double *p = xfind(x, x+10,5.0);

cout << *p << endl;


}

Posted by k1rha
2012. 8. 14. 13:59

#include<iostream>

using namespace std;


/*

class Car{


int mCount;

public :

Car() : mCount(0){}


void incStrong(){--mCount;}

void decStrong(){

if(--mCount ==0)delete this;

}

~Car(){cout<<"Car 파괴 "<<endl;}


};

*/


////////////////////////////////////////////////////////////////////////////////////////

/// 안드로이드 프레임웤에서는 모든 클래스가 RefBase 클래스를 상속받아 사용되게 되어있다.

////////////////////////////////////////////////////////////////////////////////////////

class RefBase{


int mCount;

public :

RefBase() : mCount(0){}


void incStrong(){++mCount;}

void decStrong(){

if(--mCount ==0)delete this;

}

virtual ~RefBase(){cout<<"Red 파괴 "<<endl;}


};


class Car : public RefBase{



}

template<typename T> class sp

{

T * m_ptr;

public:

sp(T *other =0):m_ptr(other) {if(m_ptr)m_ptr->incStrong();}

sp(const sp &p):m_ptr(p.m_ptr) {if(m_ptr)m_ptr->incStrong();}

~sp() {if(m_ptr)m_ptr->decStrong();}


T *operator->(){return m_ptr;}

t& operator *(){return *m_ptr;}


}

int main(){


sp<Car> p1 = new Car;

sp<Car> p2=p1;


/*

Car *p1 = new Car;

p1->incStrong(); //객체 생성후 무조껀 1을 증가하자


Car *p2 = p1;

p2->incStrong(); //복사후 1을 증가하자


p1->decStrong(); //3. 모든 포인터는 사용후 1감소하자.

p2->incStrong();

*/

}

Posted by k1rha
2012. 8. 14. 13:58

#include<iostream>

using namespace std;


//1. template 로 만들게 된다!! 당근이징 

//2. 얕은 복사를 해결 해야 한다.

//  (A) 깊은 복사

//  (B) 참조 계수

//  (C) 소유권 이전

//  (D) 복사금지 



/*

template <typename T>class ptr{

T *obj;


public:

ptr(T *p=0):obj(p){}

T *operator->(){return obj;}

T& operator*() {return *obj ;}


~ptr(){delete obj;}

};

//


int main(){

ptr<int> p1 = new int;

*p1 = 10;

cout << *p1 << endl;



}

*/

/*

////////////////////////// 복사 금지 ///////////////////////////////

// boost 의 scoped_ptr<> 이 이정책을 사용한다.

//장점 : 가볍다.

//단점 : 단지 자원곤리만 책임지고 대입 , 복사등이 불가능하다.

////////////////////////////////////////////////////////////////////


template <typename T>class scoped_ptr{

T *obj;

scoped_ptr(const scoped_ptr &p);

void operator = (const scoped_ptr &p);


public:

scoped_ptr(T *p=0):obj(p){}

T *operator->(){return obj;}

T& operator*() {return *obj ;}


~scoped_ptr(){delete obj;}

};


//void foo(scoped_ptr<int> p2); //불편함




int main(){

scoped_ptr<int> p1 = new int;

*p1 = 10;

cout << *p1 << endl;


//ptr<int> p2= p1; /// 컴파일 에러!! 절대 이렇게는 사용하지 마시요~ 라는 뜻 

}


*/

/*

//////////////////////////////////////// 소유권 이전 ///////////////////////////////

//#include<memory> // 이안에 auto_ptr 이 있다!!

//

/////////////////////////////////////////////////////////////////////////////////////

template <typename T>class Auto_ptr{

T *obj;


public:

//소유권 이전의 전략

Auto_ptr(ptr & p): obj(p.obj){

p.obj=0;

}


Auto_ptr(T *p=0):obj(p){}

T *operator->(){return obj;}

T& operator*() {return *obj ;}


~Auto_ptr(){delete obj;}

};


//void foo(scoped_ptr<int> p2); //불편함




int main(){

Auto_ptr<int> p1 = new int;

*p1 = 10;

cout << *p1 << endl;


Auto_ptr<int> p2= p1; //이제 자원은 p2만 사용한다 (소유권 이전)

//cout << * p1 < endl;//error

cout << *p2<<endl; // ok



}

*/

/////////////////////////////////// 참조 계수 /////////////////////////////////////

// boost 에서 만들고 STL 에 새롭게 추가된 shared_ptr 입니다.

/////////////////////////////////////////////////////////////////////////////////////

template <typename T>class Auto_ptr{

T *obj;

int *pRef;


public:

//참조계수 전략


Auto_ptr(T *p=0):obj(p){

pRef = new int(1);


}

ptr(const ptr &p):obj(p.obj),pRef(p.pRef){

++(*pRef);

}


T *operator->(){return obj;}

T& operator*() {return *obj ;}

~Auto_ptr(){

if(--(*pRef)==0){

dlete obj;

delete pRef;

}

}

};


//void foo(scoped_ptr<int> p2); //불편함




int main(){

Auto_ptr<int> p1 = new int;

*p1 = 10;

cout << *p1 << endl;


Auto_ptr<int> p2= p1; //이제 자원은 p2만 사용한다 (소유권 이전)

//cout << * p1 < endl;//error

cout << *p2<<endl; // ok



}

Posted by k1rha