//*/        (앞에서 / 하나 빼보시오.)
소스코드
소스코드
소스코드
/*/          (가운데 별 표시를 빼보시오.)
소스코드
소스코드
소스코드
//*/ 


#include <stdio.h>


int sumloop(int,int,int); // 재귀함수의 명시적 선언
int sumloop(int min, int max, int sum) { // 재귀함수 작성

  while (min <= max) // 재귀 종료 조건
  {
     sum += min++;
     sumloop(min,max,sum); // 재귀호출
  }
  return sum; // 마지막 합계 반환
}

void main() { 메인함수
  printf("%d\n",sumloop(1,10,0)); // 최소값, 최대값, 합계 파라미터 전달후 바로 결과를 출력하는 구조
}



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

[C, C++] 매크로함수 VS 인라인함수  (0) 2019.02.09
[C언어] 주석 TIP  (0) 2019.02.09
[C++] Vector와 List의 차이점  (0) 2019.02.08
[C++] 함수객체 ( Functor )  (0) 2019.02.08
[C++] 콜백함수( CallBack Function )  (0) 2019.02.08

C++ 환경에서 프로그래밍할 때, 자료구조는 

보통 STL를 많이 활용하는데요

vector와 list 활용시 모두 사이즈를 유연하게 할당 할 수 있다는 장점 때문에

item들을 담을 때, 동적인 할당이 요구되는 상황에서 많이 사용하죠.

하지만 이 둘은 분명 차이가 있습니다.

 

vector 부터 설명드리면,

vector는 내부적으로 배열의 구조를 지니고 있습니다.

그래서 인덱스로 요소에 접근할 경우 상수시간으로 접근 할 수 있죠.

하지만, item들이 추가되거나 삭제를 할 때는

내부적으로 임시 배열을 생성해서 복사한다음

item들을 이동시키게 됩니다. 이런 경우, 비용이 많이 들게 되고 성능이 떨어지죠.

 

반면,  list에서는

item들과의 연결이 포인터로 되어 있어

item의 추가와 삭제가 빠릅니다.

하지만, item들을 검색하는 시간은 o(n)의 비용이 발생하게 됩니다.

 

vector의 경우는 item들을 저장한 이후 변동이 별로 없다면 효과적이고

list의 경우 item의 추가 삭제가 많을 경우 유용하다고 할 수 있겠습니다. 

 

Java에서도 둘의 자료구조는 동일하게 적용됩니다.

Vector와 LinkedList가 위의 경우와 같다고 생각할 수 있습니다.

단 , ArrayList는 LinkedList와 다르다는 점을 인식하셔야 합니다. 

ArrayList는 Vector와 동일한 내부구조를 지니고 있고 다른 점은 멀티쓰레드로

공유자원으로 활용시 Vector는 한 쓰레드가 끝날 때까지 다른 쓰레드의 접근을 막는 동기화의 과정을 철저히 준수합니다.

ArrayList를 활용시 다른 쓰레드의 접근을 허용하지요.

성능을 생각하면 ArrayList이고

동기화의 과정이 준수되어야 하는 상황에서도 사실 ArrayList입니다 - _ -ㅋ;;

왜냐하면, Collection.synchronizedCollection(Collection c)로 동기화 옵션을 설정해줄 수 있기 때문입니다.

Vector는 자바 컬렉션 모델에서 초창기 모델이고 ArrayList는 wrapping된 버젼업 모델이기 때문에

Java에서는 Vector를 잘 사용하지 않는 상황입니다 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 
#include <iostream>
using namespace std;
 
 
/**
*    함수객체
*/
 
void Print(){
    cout<<"전역함수!"<<endl;
}
 
class Functor{
public:
    void operator() (){
        cout<<"함수객체!"<<endl;
    }
};
 
// 함수객체란
// 함수처럼 동작하는 객체, 함수처럼 동작하려면
// ()연산자를 정의해야합니다. 
// 다시말해 ()연산자를 오버로딩한 객체입니다.
// 함수객체는 함수자(Functor)라고 불리기도 합니다.
 
int main()
{
    Functor functor;
 
    Print();    //전역함수 호출
    functor();    //멤버함수호출 functor.operator()와 같다
 
    system("pause");
    return 0;
}
 
 
 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 
/**
*    함수객체를 사용한 콜백함수 구현
*/
 
#include <iostream>
#include <algorithm>
 
using namespace std;
 
class Functor1{ //출력
public:
    void operator()(int n){
        cout<<n<<endl;
    }
};
 
class Functor2{ //제곱
public:
    void operator()(int n){
        cout<<n*n<<endl;
    }
};
 
int main ()
{
    int arr[5] ={ 1, 2, 3, 4, 5 };
    for_each(arr, arr+5, Functor1() );
    // 임시 함수객체 Functor1을 만들어 함수로 전달
    // for_each알고리즘은 함수객체 사용자정의 타입까지도 전달받을수있다.
    // 여기서보면 전달되는 함수객체 타입이 다른데(1, 2)
    // 어떻게 그럴수 있을까? 정답은 템플릿이다.
 
    cout<<endl;
    for_each(arr, arr+5, Functor2() );
    
    system("pause");
    return 0;
}

 

장점:

함수객체는 함수처럼 동작하는 개체이므로 다른 멤버변수와 멤버함수를 가질수 있고, 일반함수에서 하지못하는 자원을 받을수 있습니다.

또한, 함수 객체의 서명이 같더라도 객체타입이 다르면 서로 전혀다른 타입으로 인식합니다.속도도 일반 함수보다 함수객체가 빠릅니다.

함수의 주소를 전달하여 콜백하는 경우 이함수 포인터는 인라인될 수 없지만(함수 포인터는 함수가 있어야하므로 인라인 함수의 복사본

함수를 만들어 냅니다) 함수 객체는 인라인될 수 있고, 컴파일러가 쉽게 최적화할 수 있습니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
 
#include <iostream>
#include <functional>
 
using namespace std;
 
/**
*    함수객체구현및 STL함수객체(less,greater, plus,minus)
*/
 
class Less{
public:
    bool operator()(int n1, int n2){
        return n1 < n2 ? true : false;
    }
};
 
class Greater{
public:
    bool operator()(int n1, int n2){
        return n1 > n2 ? true : false;
    }
};
 
class Plus{
public:
    int operator()(int n1, int n2){
        return n1+n2;
    }
};
 
class Minus{
public:
    int operator()(int n1, int n2){
        return n1-n2;
    }
};
 
 
typedef less<int> stl_less;
typedef greater<int> stl_greater;
typedef plus<int> stl_plus;
typedef minus<int> stl_minus;
 
int main()
{
    Less l;
    stl_less l2;
 
    Greater g;
    stl_greater g2;
 
    Plus p;
    stl_plus p2;
 
    Minus m;
    stl_minus m2;
 
    cout<< Less()(10,20) <<endl;        // 임시객체로 암묵적 함수호출
    cout<< l.operator()(20,10)<<endl;    // l1객체로 명시적 함수호출
    cout<< stl_less()(10, 20) <<endl;    // stl less 임시함수객체로 암묵적 함수호출
    cout<< l2.operator ()(20, 10)<<endl;// stl less l2 함수객체로 명시적 함수호출
    cout<<endl;
 
    cout<< Greater()(10, 20) <<endl;
    cout<< g.operator()(20, 10) <<endl;
    cout<< stl_greater()(10, 20) <<endl;
    cout<< g2.operator ()(20, 10)<<endl;
    cout<<endl;
 
    cout<< Plus()(10, 20) <<endl;
    cout<< p.operator()(20,10) <<endl;
    cout<< stl_plus()(10, 20)<<endl;
    cout<< p2.operator ()(20, 10) <<endl;
    cout<<endl;
 
    cout<< Minus()(10, 20) <<endl;
    cout<< m.operator()(20, 10) <<endl;
    cout<< stl_minus()(10, 20) <<endl;
    cout<< m2.operator ()(20, 10)<<endl;
 
    system("pause");
    return 0;
}
 
 
 


 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 
#include <iostream>
using namespace std;
 
/**
*    클라이언트 코드와 서버코드
*    서비스를 제공하는 코드측을 서버코드
*    그기능을 제공받는 코드측을 클라이언트코드
*/
 
//서버//
void PrintCall(){        
    cout<<"HelloWorld"<<endl;
}
 
//클라이언트//
int main(){
 
    PrintCall();
 
    /**
    *    이처럼 클라이언트가 서버를
    *    호출하게되면 Call
    *    반대로 서버가 클라이언트를 호출하게되면
    *    콜백(CallBack)
    */
 
    // 윈도우의 모든 프로시저는 시스템이 호출하는 Callback함수
 
    system("Pause");
    return 0;
}

 

 

서버에서 클라이언트 코드 호출 ( 콜백함수 )

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 
#include <iostream>
using namespace std;
 
//서버 코드영역//
void PrintCall(){
    cout<<"HelloWorld"<<endl;
    Client();
}
 
//클라이언트 코드영역//
void Client(){
    cout<<"난 클라이언트"<<endl;
}
int main(){
 
    PrintCall();
    // 서버에서 클라이언트측 코드인 Client() 함수를 호출하면
    // 이때 Client()함수를 '콜백함수'라 합니다.
 
    // 서버는 여러클라이언트에의해 호출되며 클라이언트의 존재를 알수없는데
    // 위의 예제처럼 서버에서 클라이언트 코드를 알고 호출하는것을 불가능
    // 합니다. 그래서 서버에게 알려줄필요가 있는데
    // 그방법으론 함수포인터매개변수를 이용한 콜백함수의 주소를전달하는방법
    // 객체,대리자,전략패터등을 사용
 
    // 말그대로 서버는 구체적인 작업이 없이 클라이언트 함수의 의해서 작업
    // 내용이 결정납니다.
 
    // 윈도우의 모든 프로시저는 시스템이 호출하는 Callback함수
 
    system("Pause");
    return 0;
}

 

 

// 함수포인터매개변수를 이용한 콜백함수의 주소를전달하는방법

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
#include <algorithm>
 
using namespace std;
 
//서버 코드영역//
void For_each(int *begin, int *end, void (*pf)(int) ){
    while(begin != end){
        pf(*begin++); // 클라이언트 함수 호출 콜백
    }
}
 
//클라이언트 코드영역//
void Print1(int n){
    cout<< n << endl;
}
void Print2(int n){
    cout<< n*n <<endl;
}
int main(){
 
    int arr[5] = {10, 20, 30, 40, 50};
    For_each(arr, arr+5, Print1);
    cout<<endl;
    for_each(arr, arr+5, Print2);    
 
    /**
    * 서버코드는 단지 클라이언트함수를 처음부터끝까지
    * 호출해주기만 한다. 추상화
    * 출력정책은 클라이언트에서만 알고있고, 수정한다.
    */
 
    system("Pause");
    return 0;
}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <iostream>
 
 
/**
* 정적함수포인터, 멤버함수포인터
*/
 
using namespace std;
 
 
class Point{
 
    int x;
    int y;
 
public:
    Point( int _x = 200, int _y = 300 ) : x(_x), y(_y) {}
 
    void Print(){ cout<<x<<","<<y<<endl; }
    void Print(int num){ cout<<num<<":"<<x<<","<<y<<endl; }
    void Print(int x, int y){ cout<<x<<","<<y<<endl;}
};
 
void Print( int x, int y ){
    cout<<x<<","<<y<<endl;
}
 
int main(){
 
    //[전역함수, namespace전역함수, static멤버함수]
    void (*pf)(intint) = Print; // 정적함수포인터 
    pf(1000,2000);
    /**
    * 클래스 멤버 함수포인터 선언이 다른것은
    * 함수호출규약이 틀리기때문인데, 정적함수포인터는 cdecl이고,
    * 멤버함수는 thiscall규약을 따릅니다. 
    * 
    */
 
 
 
    /**
    * pt객체로 멤버함수포인터를 이용한 호출문
    */
    Point pt(10,20);    
    void (Point::*pf2)(int) = &Point::Print;
    (pt.*pf2)(100);
 
    void (Point::*pf3)(intint ) = &Point::Print;
    (pt.*pf3)(30,40);
 
    /**
    * pt주소값으로 멤버함수포인터를 이용한 호출문
    */
    Point *pAddress = &pt;
    void (Point::*pf4)(int) = &Point::Print;
    (pAddress->*pf4)(40);
    
 
    
 
 
    system("pause");
    return 0;
}


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

[C++] 함수객체 ( Functor )  (0) 2019.02.08
[C++] 콜백함수( CallBack Function )  (0) 2019.02.08
[C++] 템플릿 (함수템플릿, 클래스템플릿)  (0) 2019.02.08
[C++] 연산자 오버로딩  (0) 2019.02.08
[C++] 가상소멸자  (0) 2019.02.08

템플릿은 STL 제너릭 프로그래밍의 핵심이다.

 

템플릿을 사용하는이유?

: 범용적으로 사용함에 있어, 미리 타입을 정하지 않고,  일반화(generic)된 프로그래밍을 하기위함

 

컴파일러가 함수 호출인자 타입을 보고 템플릿 함수의 매개변수 타입을 결정하여 실제 함수인 템플릿 인스턴스 함수를 만들어 냅니다.

 

 

 

[함수 템플릿]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
 
#include <iostream>
using namespace std;
 
/**
*    템플릿
*/
 
class Student{
    int kor_score;
    int eng_score;
public:
    Student(int _kor, int _eng ) : kor_score(_kor), eng_score(_eng){}
    void Print(int num){
        cout<<"["<<num<<"]"<<"한국사 점수 : "<<kor_score<<"점"<<endl;
        cout<<"["<<num<<"]"<<"영어 점수 : "<<eng_score<<"점"<<endl;
    }
};
 
 
template <typename T1, typename T2>    //template<class T1, class T2>
void Print(T1 arg1, T2 arg2){
    cout<< arg1 << "," << arg2 <<endl;
}
 
//템플릿특수화
template<>
void Print(int num, Student * st){
//void Print<>(int num, Student * st){
//void Print<int, Student*>(int num, Student* st){
    st->Print(num);
}
 
template <typename T1, int size>
void PrintArray( T1* arr ){
    for(int i = 0; i < size; ++i ){
        cout<<"["<<i<<"]"<<arr[i]<<endl;
    }
}
 
int main()
{
    Print(10, 20);
    Print(0.4, 0.05);
    Print("ABCD", 10);
    cout<<endl;
 
    Print<int,int>(10, 20);                //함수템플릿타입을 명시적호출
    Print<doubledouble>(0.4, 0.05);
    Print<const char*,int>("ABCD", 10);
    cout<<endl;
    //----------------------------------------------------------
 
    Student s1(100, 50);
    Student s2(90, 30);
    Print(0,&s1);    // 특수화 버전 호출
    Print(1,&s2);    // 특수화 버전 호출 Print<Point>(&s2);->명시적호출
    cout<<endl;
    //----------------------------------------------------------
    int arr[5] = { 1, 2, 3, 4, 5 };    
    PrintArray<int, 5>(arr);
    // 여기서 이렇게 템플릿을 명시적으로 호출해야만 한다.
    // 왜냐하면 T1이라는 정보만을 제공하므로 5라는 템플릿 매개변수 인자를
    // 클라이언트 코드만으로 컴파일러가 추론할 수 없기 때문
 
    //-----------------------------------------------------------
 
    system("pause");
    return 0;
}

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include <string>
using namespace std;
 
/**
* 함수객채(printFunctor)를 사용한 For_each
*/
 
template <typename IterT, typename Func>
void For_each(IterT begin,IterT end, Func pf )
{
    while( begin != end )
    {
        pf( *begin++ ); 
    }
}
 
template <typename T>
struct PrintFunctor
{
    string sep; // 출력 구분자 정보 seperator
public:
    explicit PrintFunctor(const string& s=" "):sep(s) { }
    void operator()(T data) const
    {
        cout << data <<sep;
    }
};
 
void main( )
{
    int arr[5] = {10, 20, 30, 40, 50};
    For_each(arr, arr+5, PrintFunctor<int>());  // 명시적 호출을 해줘야 한다.
    cout << endl;                                // 그렇지 않으면 컴파일러가 
                                                // typename T 를알수없다.
 
    string sarr[3] = {"abc","ABCDE","Hello!"};
    For_each(sarr, sarr+3, PrintFunctor<string>("*\n")); // 구분자 *
    cout << endl;
}
 
 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <string>
using namespace std;
 
/**
*    반환타입과 매개변수 타입을 인자로 갖는 함수객체
*/
 
template <typename RetType, typename ArgType>
class Functor
{
public :
    RetType operator( ) (ArgType data)
    {
        cout << data << endl;
        return RetType();
    }
};
void main( )
{
    /**
    *    템플릿의 매개변수와 함수 객체를 결합하면 반환타입과
    *    함수매개변수 타입을 클라이언트가 결정하는 아주 유연한
    *    함수객체를 만들수 있습니다.
    */
    Functor< voidint > functor1;
    functor1( 10 );
    Functor< bool, string > functor2;
    functor2( "Hello!" );
}

 

 

[클래스 템플릿]

 

 

실제로 메타 클래스(클래스를 만드는 클래스)이다. 그리고 이것을 메타프로그래밍이라고 한다. 본질적으로 메타프로그래밍은 프로그램 작성시가 아닌 실행 중 코드를 변경하거나 생성함을 말한다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <iostream>
#include <string>
using namespace std;
 
/**
*    클래스 템플릿
*    :클래스를 만들어내는 틀(Meta코드)
*/
 
#include <iostream>
using namespace std;
 
template < typename T1=intint capT = 100 > //디폴트 매개변수
class Array{
    T1 *arr;
    int size;
    int capacity;
 
public:
    explicit Array(int cap = capT) : arr(NULL), size(0), capacity(cap) {
        arr = new T1[capacity];
    }
    ~Array(){
        delete [] arr;
    }
 
    void Add( T1 data ){
        if( size > capacity)
            throw "오바";
 
        arr[size++] = data;    
    }
    void print() const{
        for(int i = 0; i < size; ++i)
            cout<<"["<<i<<"] "<<arr[i]<<endl;
    }
    int Size() const{
        return size;
    }
    T1& operator[](int idx){
        return arr[idx];
    }
    T1 operator[](int idx) const{
        return arr[idx];
    }    
};
 
int main(){
    
    Array<int> arr; // 정수(클라이언트가 T타입 결정) Array객체
    //Array<> arr;    // 디폴트 매개변수값을 갖는 선언
    try{
        arr.Add(10);
        arr.Add(20);
        arr.Add(30);
    }catchchar * pStrException ){ cout<<pStrException<<endl; }    
    arr.print();
 
    Array<string> sarr; // 문자열
    try{
        sarr.Add("abc");
        sarr.Add("ABC");
        sarr.Add("Hello!");
    }catchchar * pStrException ){ cout<<pStrException<<endl; }    
    sarr.print();
 
 
    system("pause");
    return 0;
}

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
#include <string>
using namespace std;
 
/**
*    클래스 템플릿 특수화
*/
template <typename T>
class ObjectInfo
{
    T data;
public:
    ObjectInfo(const T& d):data(d) { }
    void Print( )
    {
        cout <<"타입 : "<< typeid(data).name() << endl;
        cout <<"크기 : "<< sizeof(data) << endl;
        cout <<"값 : "<< data << endl;
        cout <<endl;
    }
};
template <> // T를 string으로 특수화(클래스 템플릿 특수화)
class ObjectInfo<string>
{
    string data;
public:
    ObjectInfo(const string& d):data(d) { }
    void Print( )
    {
        //cout <<"타입 : "<< typeid(data).name() << endl;
        cout <<"타입 : "<< "string" << endl; //타입 정보 수정
        //cout <<"크기 : "<< sizeof(data) << endl;
        cout <<"문자열 길이 : "<< data.size() << endl; //길이 정보 수정
        cout <<"값 : "<< data << endl; 
        cout <<endl;
    }
};
void main( ) 
{
    ObjectInfo<int> d1(10);
    d1.Print( ); // 객체 정보 출력
 
    ObjectInfo<double> d2(5.5);
    d2.Print( ); // 객체 정보 출력
 
    ObjectInfo<string> d3("Hello!");
    d3.Print( ); // 객체 정보 출력
}
 

 

 

 

 

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

[C++] 콜백함수( CallBack Function )  (0) 2019.02.08
[C++] 정적함수포인터, 멤버함수포인터  (0) 2019.02.08
[C++] 연산자 오버로딩  (0) 2019.02.08
[C++] 가상소멸자  (0) 2019.02.08
[C언어] 10진수를 2진수로  (0) 2019.02.08

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include <iostream>
 
/**
* 연산자 오버로딩
*/
 
using namespace std;
 
class Point {
 
    int x;
    int y;
 
public:
    explicit Point( int _x, int _y ){ x = _x; y = _y; }    
 
    /**
    * 단항
    */
    const Point&operator++(){
        ++x;
        ++y;
        return *this;
    }
    const Point operator++(int){
        Point tmp( x, y );
        ++x;
        ++y;
        return tmp;
    }
 
    /**
    * 이항
    */
    bool operator== ( const Point& p2 ){
 
        return x == p2.x && y == p2.y ? true : false;
    }
    void Print() { cout<<x<<","<<y<<endl;}
 
 
    /**
    * 배열인덱스 연산자
    */
 
    int operator[] (int idx ) const {
        if( idx == 0 ) return x;
        else if( idx == 1 ) return y;
        else throw "이럴순 없다";
    }
};
 
int main()
{
    Point p1(10, 20), p2(10, 20);
    Point ret(0,0);
 
//    ret = p1++;
 
    p1.Print();
    ret.Print();
 
    bool bRet = p1 == p2;
    printf("%d\n", bRet);
 
 
    try
    {
        Point(1,2)[3];
    }
    catch(char* pStrexception){
        printf("%s\n", pStrexception);
    }
     
    system("pause");
    return 0;
}

 

 

//스마트 포인터 ->,* 연삱자 오버로딩

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
using namespace std;
 
class Point
{
    int x;
    int y;
public:
    Point(int _x =0 , int _y =0 ):x(_x),y(_y) { }
    void Print( ) const { cout << x <<',' << y << endl; }
};
class PointPtr
{
    Point *ptr;
public:
    PointPtr(Point *p):ptr(p) { }
    ~PointPtr( )
    {
        delete ptr;
    }
    Point* operator->()const
    {
        return ptr;
    }
    Point& operator*()const
    {
        return *ptr;
    }
};
void main()
{
    Point* p1 = new Point(2,3); //일반 포인터
    PointPtr p2 = new Point(5,5); //스마트 포인터
 
    p1->Print(); //p1->Print() 호출 
    p2->Print(); //p2.operator->()->Print() 호출 
    cout << endl;
 
    (*p1).Print(); //(*p1).Print() 호출
    (*p2).Print(); //p1.operator*().Print() 호출
 
    delete p1;
    //p2의 소멸자에서 Point 동적 객체를 자동 메모리 제거합니다.
}

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
 
/**
* 함수 호출 연산자오버로딩()
*/
 
#include <iostream>
 
 
using namespace std;
 
 
 
class FuncObj{    
public:
    void operator() (int arg) const {
        cout<<"정수 : "<<arg<<endl;        
    }
 
    void operator() (int arg1, int arg2 ) const {
        cout<<"정수 : "<<arg1<<","<<arg2<<endl;
    }
 
    void operator() (int arg1, int arg2, int arg3 ) const {
        cout<<"정수 : "<<arg1<<","<<arg2<<","<<arg3<<endl;
    }
};
 
 
void Print1(int arg){
    cout<<"정수 : "<<arg<<endl;
}
 
 
int main(){
 
    void (*Print2)(int) = Print1;
    FuncObj Print3;
 
    Print1(10);    // 함수호출을 이용한 연산자 오버로딩
    Print2(10); // 함수포인터를 이용한 연산자 오버로딩
    Print3(10); // 함수객체를 이용한 연산자 오버로딩
    FuncObj()(10,20,30); // 임시객체를 이용한 연산자오버로딩된 함수호출
                         // 임시객체는 이문장이 끝이나면 소멸된다.
 
 
    system("pause");
    return 0;
}

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/**
* 배열 인덱스 연산자오버로딩
*/
 
#include <iostream>
using namespace std;
 
class Array{
 
    int *arr;
    int size;
    int capacity;
 
public:
    explicit Array(int cap = 1) : arr(NULL), size(0), capacity(cap) {
        arr = new int[capacity];
    }
 
    void Add( int data ){
 
        if( size > capacity)
            throw "오바";
        arr[size++] = data;    
    }
    int Size() const{
        return size;
    }
    int& operator[](int idx){
        return arr[idx];
    }
    int operator[](int idx) const{
        return arr[idx];
    }    
};
 
 
int main(){
 
    Array ar(10);
 
    try{
        ar.Add(10);
    }catchchar * pStrException ){
 
        cout<<pStrException<<endl;
    }    
    try{
        ar.Add(20);
    }catchchar * pStrException ){
 
        cout<<pStrException<<endl;
    }    
    try{
        ar.Add(30);
    }catchchar * pStrException ){
 
        cout<<pStrException<<endl;
    }    
 
    ar[0] = 90;
    const Array &ar2 = ar;
    //ar2[0] = 100;
    
    forint i = 0; i < ar.Size(); ++i )
        cout<< ar[i] <<endl;
    cout<<ar2[0]<<endl;
 
    system("pause");
    return 0;
}

 

Point operator+(const Point& p );

 

멤버함수로 오버로딩된경우

: p1.operator+( p2 ) ;

 

전역함수로 오버로딩 된경우

: operator+(p1, p2);

+ Recent posts