함수 객체

-> 객체를 함수처럼 사용하는 것이다.

-> 함수 호출 연산자를 연산자 오버로딩하여 객체를 함수처럼 사용한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class CObj
{
public:
    int operator()(int _a, int _b)
    {
        return _a + _b;
    }
};
 
void main()
{
    CObj functor;
    cout << functor(1020<< endl;
    // == functor.operator()(10, 20)
}
cs

 

 

함수 객체를 통해 BubbleSort 구현

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
class CSortRule
{
public:
    virtual bool operator()(int _a, int _b) = 0;
};
 
// 오름차순
class CAscending : public CSortRule
{
public:
    virtual bool operator()(int _a, int _b)
    {
        return _a > _b;
    }
};
// _Descending
class CDescending : public CSortRule
{
public:
    virtual bool operator()(int _a, int _b)
    {
        return _a < _b;
    }
};
void BubbleSort(int _iArr[], int _iSize, CSortRule& _Functor)
{
    for (int i = 0; i < _iSize - 1++i)
    {
        for (int j = 0; j < _iSize - 1++j)
        {
            if (_Functor(_iArr[j], _iArr[j + 1]))
            {
                int iTemp = _iArr[j];
                _iArr[j] = _iArr[j + 1];
                _iArr[j + 1= iTemp;
            }
        }
    }
}
 
void main()
{
 
    CAscending            _Ascending;
   CDescending           _Descending;
 
    int iArr[5= { 14253 };
 
    BubbleSort(iArr, 5, _Descending);
 
    for (int i = 0; i < 5++i)
        cout << iArr[i] << endl;
}
cs

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

C++ 시간 복잡도  (0) 2020.09.27
C++ 함수 템플릿, 클래스 템플릿  (0) 2020.09.23
C++ 임시 객체  (0) 2020.09.23
C++ 연산자 오버로딩(operator)  (0) 2020.09.23
C++ 인라인  (0) 2020.09.23

임시 객체

-> 임시 메모리 영역이 등록된 객체이다.

-> 일반 객체는 자료형 + 변수명으로 선언한다.

-> 임시 객체는 변수명이 없다.

 

일반 객체

-> 함수가 종료될 때까지 메모리에 상주한다.

임시 객체

-> 코드 라인을 벗어나는 즉시 소멸한다.

 

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

C++ 함수 템플릿, 클래스 템플릿  (0) 2020.09.23
C++ 함수 객체  (0) 2020.09.23
C++ 연산자 오버로딩(operator)  (0) 2020.09.23
C++ 인라인  (0) 2020.09.23
C++ 바인딩  (0) 2020.09.21

연산자 오버로딩(operator)

-> 함수 오버로딩의 규칙을 연산자에 적용하는 문법

-> 연산자 오버로딩은 연산자의 좌측 객체 기준으로 호출한다.(멤버 함수와 같음) 

 

operator+ 구현

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
class CObj
{
public:
    CObj(int _a, int _b) : m_iA(_a), m_iB(_b) {}
 
public:
    void Func()
    {
        cout << "m_iA: " << m_iA << endl;
        cout << "m_iB: " << m_iB << endl;
    }
 
  
public:
    CObj operator+(CObj& _obj)
    {
        CObj    Temp(m_iA + _obj.m_iA, m_iB + _obj.m_iB);
        return Temp;        
    }
 
 
private:
    int        m_iA;
    int        m_iB;
};
 
void main()
{    
    CObj    obj1(10100);
    CObj    obj2(20200);
 
    CObj    obj3 = obj1 + obj2;
    obj3.Func();
 
    CObj    obj4 = obj1.operator+(obj2);    
}
cs

 

operator= 구현

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
class CObj
{
public:
    CObj() {}
    CObj(int _a, int _b) : m_iA(_a), m_iB(_b) {}
 
public:
    void Func()
    {
        cout << "m_iA: " << m_iA << endl;
        cout << "m_iB: " << m_iB << endl;
    }
public:
    CObj& operator=(CObj& _obj)
    {
        m_iA = _obj.m_iA;
        m_iB = _obj.m_iB;
        
        return *this;
    }
 
public:
    CObj operator+(CObj& _obj)
    {
        CObj    Temp(m_iA + _obj.m_iA, m_iB + _obj.m_iB);
        return Temp;
    }
 
private:
    int        m_iA;
    int        m_iB;
};
 
void main()
{
    CObj    obj3 = obj1 + obj2;
    CObj    obj4;
    obj4 = obj1 + obj2;
}
cs

 

 

객체 생성과 동시에 대입은 복사 생성자의 호출이다.

-> 객체 생성 후 대입은 대입 연산자의 호출이다.(디폴트 대입 연산자)

-> 디폴트 대입 연산자 또한 구현한 내용처럼 단순 대입이다.

-> 멤버로 동적할당한 주소를 가지는 변수가 있을 경우에는 깊은 복사 방식으로 구현을 하는 것이 좋다.

 

operator 객체 + 정수 구현

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
class CObj
{
public:
    CObj(int _a, int _b) : m_iA(_a), m_iB(_b) {}
 
public:
    void Func()
    {
        cout << "m_iA: " << m_iA << endl;
        cout << "m_iB: " << m_iB << endl;
    }
 
public:
    CObj operator+(CObj& _obj)
    {
        CObj    Temp(m_iA + _obj.m_iA, m_iB + _obj.m_iB);
        return Temp;
    }
    CObj operator+(int _x)
    {
        CObj    Temp(m_iA + _x, m_iB + _x);
        return Temp;
    }
 
private:
    int        m_iA;
    int        m_iB;
};
 
 
CObj operator+(int _x, CObj& _obj);
void main()
{    
    CObj    obj4 = obj1 + 1000;
    CObj    obj5 = obj1.operator+(1000);
    
    CObj    obj6 = 1000 + obj1;
 
    obj6.Func();
}
 
CObj operator+(int _x, CObj& _obj)
{
    CObj Temp = _obj + _x;
    return Temp;
 
    return _obj + _x;
}
cs

 

 

연산자 오버로딩은 좌측 객체 기준으로 수행한다.

-> 하지만 다음과 같은 경우에는 좌측에 객체가 있는 것이 아닐 경우 호출이 불가능하다.

-> 이를 해결하기 위해서는 교환 법칙을 구현하면 된다.

 

교환 법칙

-> 전역에 정의해야한다.(전역 함수)

-> 인자 중 하나는 객체 또는 객체의 레퍼런스 타입이 와야만 한다.

 

단항 연산자 오버로딩

-> ++, --

 

전위 증감 연산자 오버로딩

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
class CObj
{
public:
    CObj(int _a, int _b) : m_iA(_a), m_iB(_b) {}
 
public:
    void Func()
    {
        cout << "m_iA: " << m_iA << endl;
        cout << "m_iB: " << m_iB << endl;
    }
 
public:    
    CObj& operator++()
    {
        m_iA += 1;
        m_iB += 1;
 
        return *this;
    }
private:
    int        m_iA;
    int        m_iB;
};
 
void main()
{    
    CObj    obj1(10100);
 
    (obj1++).Func();
    obj1.Func();
}
cs

 

 

후위 증감 연산자 오버로딩

1
2
3
4
5
6
7
8
9
CObj operator++(int)
{
    CObj Temp(*this);
 
    m_iA += 1;
    m_iB += 1;
 
    return Temp;
}
cs

여기서 매개변수에 명시한 타입은 인자를 받겠다는 의미가 아니다.

단지, 전위와 후위를 구분하기 위한 용도로 사용한다.

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

C++ 함수 객체  (0) 2020.09.23
C++ 임시 객체  (0) 2020.09.23
C++ 인라인  (0) 2020.09.23
C++ 바인딩  (0) 2020.09.21
C++ 캐스팅(static_cast, dynamic_cast, const_cast, reinterpret_cast)  (0) 2020.09.18

인라인 함수

-> 매크로 함수의 장점을 취하고, 단점을 보완한 함수

1
2
3
4
5
6
#define SQUARE(x) (x) * (x)
 
inline int Square(int _x)
{
    return _x * _x;
}
cs

매크로의 단점

##1. 디버깅 불가

##2. 복잡한 함수

 

인라인 함수가 일반 함수로 바뀌는 경우

#1. 함수 포인터로 이용할 경우

#2. 재귀형태로 함수를 호출할 경우

#3. 컴파일러 버그

-> inline 키워드가 있어도 컴파일러의 판단에 따라 일반 함수가 될 수가 있고,

-> 반대로 inline 키워드가 없어도 인라인 함수가 될 수도 있다.

 

 

인라인 함수의 주의사항

-> 헤더파일에 함수의 정의부까지 구현해야 한다.

-> 그런데, 헤더파일에 함수의 정의부를 모두 구현할 경우 파일 분할의 목적이 사라지게 된다.

-> 그렇기 때문에 한줄 짜리만 대부분 인라인을 사용한다.

-> 전역 함수 일 경우 파일 분할 시 주의사항과 중복된 내용이 있기 때문에 inline 키워드를 무조건 명시해야만 한다.

-> 헤더파일에 함수의 정의부를 모두 구현할 경우 파일 분할의 목적이 사라지게 된다.

+ Recent posts