posted by 갱우덩 2019. 1. 14. 18:39



Sort 함수  이런걸 define으로 그냥 쓸까 고민하다가


  1. #define MAX(a,b) \  
  2. ({ __typeof__ (a) _a = (a); \  
  3. __typeof__ (b) _b = (b); \  
  4. _a > _b ? _a : _b; })  
  5.   
  6. #define MIN(a,b) \  
  7. ({ __typeof__ (a) _a = (a); \  
  8. __typeof__ (b) _b = (b); \  
  9. _a < _b ? _a : _b; }) 


STL sort가 data Type에 상관없이 쓸수 있는거 같아서 역시 퍼놓습니다.


Pair 같은 것에 대해서 기본적으로 sort를 제공해주는게 참 좋네요. pair에 대해서도 재정의를 해야 되나 싶어서


고민했는데~ ㅎㅎ~ 다행~ 한번씩 참고~




(펌 : https://www.acmicpc.net/blog/view/22)


STL sort 튜토리얼


1. 정의

알고리즘 헤더파일에서 제공하는 STL로써 범위내에서 주어진 범위내에서 원소들을 정렬합니다. 이때 정렬하는 방식(오름차순, 내림차순 등등등)은 사용자가 정의할 수 있으며, 동일한 원소에 대해서는 그 순서가 보장되지 않습니다. 이때 std::sort는 숫자 뿐만 아니라 대소 비교가 가능한 모든 원소에 대해서 정렬을 할 수 있습니다. 즉 int 뿐만 아니라 char, string 역시 정렬이 가능하고, 사용자가 정의한 객체 역시 연산자 오버로딩('<')을 정의해주면 정렬이 가능합니다. 또한 동일한 원소에 대해서 그 원소들의 상대적 순서를 보장해 주는 라이브러리도 존재합니다.

자세한 내용은 여기를 참고해 주세요.

2. 특징

2개의, 혹은 3개의 argument를 필요로 하는데, 첫번째 두개의 argument는 iterator로써 정렬하는 범위를 나타냅니다. 이때 iterator는 random access와, 수정이 가능해야 합니다. 기본적으로 Strick week Ordering, 즉 두개의 객체를 비교해서 첫번째가 두번째보다 작으면 true 그렇지 않다면 false를 리턴합니다. 대부분 quick sort를 사용한다고 알려져 있지만 대부분의 컴파일러에서 다양한 방식의 정렬을 복합적으로 사용합니다. GCC의 경우 introsort와 원소의 개수가 적을 경우 insertion sort를 사용한다고 알려져 있습니다.

자세한 내용은 여기를 참고해 보세요.

3. 사용법

기본 사용법

template <class RandomAccessIterator>
  void sort (RandomAccessIterator first, RandomAccessIterator last);
template <class RandomAccessIterator, class Compare>
  void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

배열 정렬

기본적으로 std::sort를 이용하면 오름차순 정렬이 수행됩니다.

소스예제

#include <iostream>
#include <algorithm>

using namespace std;

int main(){

    int arr[5];
    arr[0] = 0;
    arr[1] = 4;
    arr[2] = 3;
    arr[3] = 1;
    arr[4] = 5;
    sort(arr, arr + 5);

    for (int i = 0; i < 5; i++)
        cout << arr[i] << endl;

    return 0;
}

결과

0
1
3
4
5

정렬 오름차순(greater)

내림차순 정렬을 수행하기 위해서 fuctional 헤더에서 제공하는 less를 사용하는 방법입니다.

소스예제

#include <iostream>
#include <functional>
#include <algorithm>

using namespace std;

int main(){
    int arr[5];
    arr[0] = 0;
    arr[1] = 4;
    arr[2] = 3;
    arr[3] = 1;
    arr[4] = 5;

    sort(arr, arr + 5, greater<int>());

    for (int i = 0; i < 5; i++)
        cout << arr[i] << endl;

    return 0;
}

결과

5
4
3
1
0

vector의 정렬

숫자 뿐만 아니라 대소비교가 가능한 모든 변수형은 정렬이 가능합니다.

소스예제

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main(){
    vector<char> v;
    v.push_back('c');
    v.push_back('b');
    v.push_back('e');
    v.push_back('a');
    v.push_back('g');

    sort(v.begin(), v.end());

    for (int i = 0; i < 5; i++)
        cout << v[i] << endl;

    return 0;
}

결과

a
b
c
e
g

사용자 정의 객체 정렬 (global < operator)

연산자 오버로딩을 통해서 사용자 정의 객체를 정렬해 봅시다.

소스예제

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>

using namespace std;

class Person{
public:
    string name;
    int age;
    Person(string name, int age){
        this->name = name;
        this->age = age;
    }
};

bool operator <(const Person &a, const Person &b){
    return a.age < b.age;
}

int main(){
    vector<Person> v;
    v.push_back(Person("MinJi", 22));
    v.push_back(Person("Kangho", 28));
    v.push_back(Person("Minho", 26));
    v.push_back(Person("Strange Yun", 25));
    sort(v.begin(), v.end());
    for (int i = 0; i < v.size(); i++)
        cout << v[i].age  << ", " <<  v[i].name << endl;

}

결과

22, MinJi
25, Strange Yun
26, Minho
28, Kangho

객체 정렬 (클래스내 연산자 오버로딩)

소스예제

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>

using namespace std;

class Person{
public:
    string name;
    int age;
    Person(string name, int age){
        this->name = name;
        this->age = age;
    }
    bool operator <(const Person &a) const {
        return this->age < a.age;
    }

};

int main(){
    vector<Person> v;
    v.push_back(Person("MinJi", 22));
    v.push_back(Person("Kangho", 28));
    v.push_back(Person("Minho", 26));
    v.push_back(Person("Strange Yun", 25));
    v.push_back(Person("JunEun", 40));
    sort(v.begin(), v.end());
    for (int i = 0; i < v.size(); i++)
        cout << v[i].age  << ", " <<  v[i].name << endl;

}

결과

22, MinJi
25, Strange Yun
26, Minho
28, Kangho
40, JunEun

객체 정렬 (사용자 정의 함수)

이름을 기준으로 내림차순 정렬하는 사용자 정의 함수를 작성해봅니다.

예제소스

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>

using namespace std;

class Person{
public:
    string name;
    int age;
    Person(string name, int age){
        this->name = name;
        this->age = age;
    }
};

bool cmp(const Person &a, const Person &b){
    return a.name > b.name;
}

int main(){
    vector<Person> v;
    v.push_back(Person("Ace", 22));
    v.push_back(Person("Luffy", 28));
    v.push_back(Person("Zoro", 26));
    v.push_back(Person("Robin", 25));
    v.push_back(Person("Brook", 40));
    sort(v.begin(), v.end(), cmp);
    for (int i = 0; i < v.size(); i++)
        cout << v[i].age  << ", " <<  v[i].name << endl;
}

결과

26, Zoro
25, Robin
28, Luffy
40, Brook
22, Ace

STL Pair의 정렬

많이 쓰이는 STL의 pair을 sort함수로 정렬할 경우 기본적으로 pair의 첫번째 원소를 기준으로 정렬이 되고 첫번째 원소가 같을 경우 두번째 원소를 사용해서 비교하게 됩니다.

예제소스

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>

using namespace std;

int main(){
    vector<pair<int, string> > v;
    v.push_back(pair<int, string>(20, "A_Jiwoo"));
    v.push_back(pair<int, string>(21, "B_Songju"));
    v.push_back(pair<int, string>(21, "C_Induk"));
    v.push_back(pair<int, string>(21, "D_SeungHyun"));
    v.push_back(pair<int, string>(20, "E_Soyen"));

    sort(v.begin(), v.end());
    for (int i = 0; i < v.size(); i++)
        cout << v[i].first  << ", " <<  v[i].second << endl;

}

결과

20, A_Jiwoo
20, E_Soyen
21, B_Songju
21, C_Induk
21, D_SeungHyun


posted by 갱우덩 2017. 2. 7. 13:39


(펌) - http://blog.naver.com/PostView.nhn?blogId=vosej_v&logNo=50176084445&redirect=Dlog&widgetTypeCall=true


string class
Header : <string>


.assign : 문자열을 할당
( 문자열 ) : 문자열을 할당한다.
( 개수, 문자 ) : 문자를 개수만큼 할당한다
( 문자열, 시작위치, 개수 ) : 매개변수 문자열의 시작위치부터 개수만큼을 호출한 문자열에 할당


  string s1, s2, s3 ;

  s1.assign( "ABCDEFG" ) ;     // s1 = "ABCDEFG"

  s2.assign( 3, 'a' ) ;               // s2 = "aaa"

  s3.assign( s, 2, 4 ) ;             // s3 = "CDEF" ( 문자열 s의 2부터 4개를 복사하여 할당 )




.append : +연산자의 역할처럼 문자열을 끝에 더한다.
( 문자열 ) : 문자열을 더한다
( 개수, 문자 ) : 문자를 개수만큼 끝에 더한다
( 문자열, 시작위치, 개수 ) :


  string s, s2 ;

  s.append( "ABCDEF" ) ;      // s = "ABCDEF"

  s.append( 3, 'x' ) ;              // s = "ABCDEFxxx"

  s2.append( s, 2, 4 ) ;          // s2 = "CDEF"

  s2 += "x" ;                          // s2 = "CDEFx"

 



.clear : 문자열의 내용을 모두 삭제

  s.clear() ;



.compare : 문자열을 비교 ( 사전순으로 비교 )

  s.compare( s2 ) ;          // s == s2이면 0,  s<s2이면 음수,  s>s2이면 양수를 반환



.empty : 문자열이 비었는지 확인

  s.empty() ;



.erase : 문자열을 지운다
( 시작위치, 개수 ) : 시작위치부터 개수만큼의 문자를 지운다. 

 

  string s = "ABCDEF" ;

  s.erase( 0, 3 ) ;                // s = "DEF" ( 인덱스 0부터 3개의 문자를 지운다 )

 



.find : 특정 문자열을 찾고, 그 시작위치를 반환
( 문자 ) : 인덱스 0부터 해당 문자를 찾고, 시작위치를 반환한다.
( 문자열 ) : 인덱스 0부터 해당 문자열을 찾고, 그 시작위치를 반환한다.
( 문자열, 시작위치 ) : 시작위치부터 문자열을 찾고, 시작위치를 반환한다.

 

  string s1 = "abcd" ;

  string s2 = "b" ;

 

  int location = s1.find( s2 ) ;

  location = s1.find( s2, x ) ;

  location = s1.find_first_of( s2, x ) ;

  location = s1.find_first_not_of( s2, x ) ;  

  location = s1.find_last_of

  s1.find_last_not_of




.replace : 문자열을 대체
( 시작위치, 개수, 문자열 ) : 호출한 문자열의 시작위치부터 개수만큼의 문자를 매개변수 문자열로 대체한다.

 

  string s = "abc_def" ;

  s.replace( 4, 3, "zzz" ) ;                // s = "abc_zzz"  ( 인덱스 4부터 3개의 문자를 "zzz"로 대체 )

 



.insert : 문자열을 지정한 위치에 삽입
( 시작위치, 문자열 ) : 시작위치에 문자열을 삽입한다.

 

  string s = "ABCDEF" ;

  s.insert( 2, "xx" ) ;                         //  s = "ABxxCDEF"

 



.pop_back : 문자열에서 가장 뒤의 문자 하나를 빼낸다.
.push_back : 문자열의 가장 뒤에 문자 하나를 추가한다.

 

  string s = "ABCDEF" ;

  s.pop_back() ;                               // s = "ABCDE"

  s.push_back( 'x' ) ;                        // s = "ABCDEx"

 



.resize : 문자열의 크기를 재설정

 

  s

 



.size, .length : 문자열의 크기를 반환
.max_size : 문자열이 최대로 가질수 있는 길이를 반환한다.

 

  string s = "ABCDEF" ;

  int size = s.size() ;                    // size = 6         ( 실제 사용되고 있는 크기 )

  int length = s.length() ;             // length = 6     ( 문자열의 길이 )

 



.capacity : 할당된 메모리의 크기를 반환 ( reallocation 없이 사용할 수 있는 문자수를 반환 )

 

  string s = "ABCDEF" ;

  int capacity = s.capacity() ;       // size = 6, capacity = 15

 

capacity가 size보다 클때, 속도는 더 빠르다 !
 = capacity가 size보다 크면, 기존 공간에 문자를 추가하면 되지만
    그 반대의 경우에는 문자를 추가하기 위해 새로운 메모리를 할당해야 하기 때문이다.


.reserve : reallocation을 피하기 위해, 메모리의 최소용량을 지정
( 크기 ) : 크기만큼의 여유 메모리를 할당한다.
** 이때, 매개변수의 크기는 현재 capacity보다 크지않으면 의미도 효과도 없다.

 

  string s = "ABCDEF" ;             // size = 6, capacity = 15

  s.reserve( 100 ) ;                   // size = 6, capacity = 111

  s.reserve( 1000 ) ;                 // size = 6, capacity = 1007

 



.substr : 문자열의 일부분을 문자열로 반환
( 시작위치 ) : 시작위치부터 끝까지의 문자들을 문자열로 반환
( 시작위치, 개수 ) : 시작위치부터 개수만큼의 문자를 문자열로 반환

 

  string s = "ABCDEF" ;

  string s2 = s.substr( 4 ) ;        // s2 = "EF"    ( 인덱스 4부터 끝까지의 문자열을 반환 )

  string s3 = s.substr( 1, 3 ) ;    // s3 = "BCD" ( 인덱스 1부터 3까지의 문자열을 반환 )

 



.swap : 문자열을 서로 바꾼다

 

  string a = "ABCD" ;

  string b = "WXYZ" ;

  a.swap( b ) ;                            // a = "WXYZ", b = "ABCD"

  b.swap( a ) ;                            // a = "ABCD", b = "WXYZ"

 



.at : 문자열에서 특정위치의 문자를 액세스

 

  string s = "ABCDEF" ;

  char c = s.at(3) ;                      // c = 'D'

 



.c_str : string 문자열을 char* 형으로 바꾸어 반환한다.

 

  string s = "ABCDEF" ;

  int length = strlen( s.c_str() ) ;  

 


.date
.copy
.back
.front
.begin


posted by 갱우덩 2017. 2. 7. 13:30


(펌) : http://makerj.tistory.com/127#string간의-문자열-비교

string 생성


방법1

string myString = "abcd"; 
단, 이 방식으로는 'a'와 같은 char로 생성이 불가능하다. 따라서 이 한계를 극복하려면 방법 2를 써야한다.

방법2

string myString;
myString = "abcd";

string 확장, 문자열 추가


방법1: += 연산자 이용

string base = "hello world!";
base += "x";

방법2: append() 멤버 함수 이용

string base = "hello world!";
base.append("appended!");

string 길이


string base = "hello world!";
base.length();
base.size();

size()와 length()는 이름만 다를 뿐 같은 일을 하는 멤버 함수다.

메모리 관련


capacity()

string base = "hello world!";
base.capacity();

capacity()는 해당 문자열이 재할당을 하지 않고도 저장할 수 있는 문자열의 길이를 반환한다. 
문자열은 문자열이 늘어났을 때, 현재 capacity보다 클 경우 더 큰 메모리를 사용할 수 있도록 재할당된다.

max_size()

string base = "hello world!";
base.max_size();

myString.max_size()는 최대한 메모리를 할당했을 경우, 저장할 수 있는 문자열의 길이를 반환한다.

string의 특정 위치 문자 받기(charAt)


string base = "hello world!";
base.at(0); // 'h'
base.at(1); // 'e'

해당 위치의 char를 반환한다. 
java의 String.charAt()과 같다.

string에 있는 특정 문자 탐색


string base = "hello world!";
base.find("world!");

world! 문자열이 발견된 첫 위치를 반환한다.

if (base.find("world!") != string::npos) {
    // "world!"라는 문자열을 찾았을 때의 동작
}

탐색에 실패할 경우는 if 문에서 볼 수 있듯이 string::npos를 반환한다.

string간의 문자열 복사


string src = "I am source :)";
string dst;
dst = src;

dst에는 같은 내용이 복사되어 들어간다. 
얕은 복사가 아니다. 깊은 복사다. 즉, 복사 후에 src의 내용이 변경된다고 해도 dst의 내용에는 아무 영향을 끼치지 않는다.

string간의 문자열 비교


string a = "I am string one! ;)";
string b = "string 

if (a.compare(b) == 0) {
    // 두 문자열이 같을 때
} else if (a.compare(b) < 0) {
    // a가 b보다 사전순으로 앞일 때
} else if (a.compare(b) > 0) {
    // a가 b보다 사전순으로 뒤일 때
}

string의 문자열 대체하기 (replace기능)


http://stackoverflow.com/a/14678964/2050087 참조

Immutable Replace

원본 문자열에는 아무 영향을 끼치지 않는다. 변경된 문자열은 함수의 반환값으로 돌아온다.

#include <string>
#include <iostream>

using std::string;

std::string replaceString(std::string subject, const std::string &search, const std::string &replace) {
    size_t pos = 0;
    while ((pos = subject.find(search, pos)) != std::string::npos) {
        subject.replace(pos, search.length(), replace);
        pos += replace.length();
    }
    return subject;
}

Mutable Replace

원본 문자열을 수정한다. 속도가 우선일 경우 사용하자.

void ReplaceStringInPlace(std::string& subject, const std::string& search,
                          const std::string& replace) {
    size_t pos = 0;
    while ((pos = subject.find(search, pos)) != std::string::npos) {
        subject.replace(pos, search.length(), replace);
        pos += replace.length();
    }
}

타입 변환


문자를 다른 타입으로 변경해야 할 필요가 있는 경우는 흔하다. 그래서 C++11에 들어 표준 라이브러리에 기본적인 타입 변환 기능이 추가됐다.

개발환경이 C++11을 지원해야 한다.

// int ---> string
string s;
int i = 10;

s = std::to_string(i);

// string ---> int
string s = "123";
int i;

i = std::stoi(s);



posted by 갱우덩 2015. 10. 21. 16:15

(펌. 원작 : http://rosagigantea.tistory.com/387)

 

error C2825: '_Fty': '::'가 뒤에 나오면 클래스 또는 네임스페이스여야 합니다.

이런식으로 뭔가 알지도 못하는 xxresult(28) 파일을 찾아봐염

 

에러가 떨어졌습니다.

 

아무리 이 파일 안을 봐도 뭔가 복잡한 코드라는것 밖에 알 수 없어서

이넘이 컴파일 하다 죽은 소스 부분을 살펴보다가 이런 부분이 나오더군요.

 

error C2678: 이항 '==' : 왼쪽 피연산자로 'std::tr1::_Bind_fty<_Fty,_Ret,_BindN>' 형식을 사용하는 연산자가 없거나 허용되는 변환이 없습니다.
1> with
1> [
1> _Fty=SOCKET,
1> _Ret=std::tr1::_Notforced,
1> _BindN=std::tr1::_Bind2<std::tr1::_Callable_obj<SOCKET,false>,sockaddr *,unsigned int>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\exception(470): 'bool std::operator ==(const std::_Exception_ptr &,const std::_Exception_ptr &)'일 수 있습니다.
1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\exception(475): 또는 'bool std::operator ==(std::_Null_type,const std::_Exception_ptr &)'
1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\exception(481): 또는 'bool std::operator ==(const std::_Exception_ptr &,std::_Null_type)'
1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\system_error(408): 또는 'bool std::operator ==(const std::error_code &,const std::error_condition &)'
1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\system_error(416): 또는 'bool std::operator ==(const std::error_condition &,const std::error_code &)'
1> C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\guiddef.h(192): 또는 'int operator ==(const GUID &,const GUID &)'
1> 인수 목록 '(std::tr1::_Bind_fty<_Fty,_Ret,_BindN>, int)'을(를) 일치시키는 동안
1> with
1> [
1> _Fty=SOCKET,
1> _Ret=std::tr1::_Notforced,
1> _BindN=std::tr1::_Bind2<std::tr1::_Callable_obj<SOCKET,false>,sockaddr *,unsigned int>
1> ]

 

 

이게 뭔말인고 하니

#include <Winsock2.h> 에서 정의된 bind 랑

#include <functional> 에서 정의된 bind가 같은 네임스페이스 상에 있어서 충돌하는거라 하네요..


(내가 추가...)

한마디로, socket에서 쓰는 bind() 함수와 STL에서 사용하는 std::bind() 충돌문제 인듯~ 합니다.

 

뭐 어쨋든.. 저걸 해결하기 위해서 stl이 아닌 bind를 쓰고 싶으면 bind -> ::bind로 바꿔주니 문제해결... ㅠㅠ.




posted by 갱우덩 2015. 10. 20. 15:08

 


 개요 


 통상 콜백함수 구현시  함수포인터 기반으로 구현하는 방식 (보기 -> http://igotit.tistory.com/212 ) 으로는 클래스 멤버함수를 콜백으로 등록하지 못하는 단점이 있다.

 

STL (Standard Template Library) 에서 제공하는 std::function, std::bind 등을 사용하면 클래스 멤버함수도 콜백함수로 등록가능하므로 대단히 편리하다.



 STL 기반 콜백구현방법


아래 설명방식에서 "다른 곳", "이곳" 이란 표현은 함수포인터 기반 콜백구현방법 설명글 (http://igotit.tistory.com/212 )에서의 것과 동일한 것임.

 

 "이곳"에 있는 함수(클래스의 멤버함수도 가능하다.)를 다른곳(예.  다른 클래스 개체, DLL등 )에 전달하여 다른 곳에서 "이곳"의 클래스 멤버 함수를 호출하는 법에 대한 STL 기반 코딩 골격을 정리한다. 

 

 

"다른 곳" 코딩. - 아래 파란색 부분이 STL기반 구현부분 핵심에 해당함.

 

#include <functional> // std::functional 등을 사용하기 위하여 포함함.

 

typedef std::function<int(int)> pFunc; // pFunc 이라는 타입선언. 이것은 함수포인터 방식에서의 typedef int(*pFunc)(int); 에 해당함.

 

pFunc your_func;          // "이 곳"의 함수를 받을 변수선언이다. 함수포인터 방식에서와 동일함. 

 

//"이 곳"의 함수포인터로 인자를 전달하면 your_func 으로 대입해 줄 함수.

void regi_func(pFunc p_func)

{

  your_func = std::move(p_func);  

//인자로 전달받은 함수포인터를 your_func 으로 받는다.함수포인터방식에서your_func = p_func에 해당.

// (추가한 내용)

// "your_func" 처럼 직접 호출할 함수 pointer 변수에 저장할 때에만 std::move 사용하면 된다. 중간에 함수 파라미터로 값을 계속 전달할 때에는 pFunc p_func 이런식으로 계속 전달하면 됨.

}

//

void exec_func()

{

 your_func(1);  // regi_func 의 인자로 전달된 함수가 실행되는 것임.

}

 

"이곳 " 코딩.

이곳에는 int Function(int a) {... } 함수 클래스 ThisClass 의 멤버함수로 정의되어있다고 치자. 클래스 멤버함수를 "다른 곳" 의 regi_func 을 호출하면서 함수포인터를 전달한다.

regi_func(std::bind(&ThisClass::Function, this, std::placeholders::_1));

 

// 클래스멤버함수 전달시 std::bind 를 사용한다는 점. 클래스의 this 개체 전달한다는 점, 클래스 멤버함수의 인자 1개 있다는점을 표현한것이다. 비교 : 함수포인터 방식에서는 regi_func(Function); 으로 했었다.

std::placeholder 관련처리 상세.

우리가 정의한 콜백함수 Function 에 만일 인자가 없다면 기록하지 않으면 된다. 만일 인자가 3개라면 즉 Function(int a, float b, char c) 라면

위 등록함수는 아래처럼 인자수량만큼 추가하면 된다.

regi_func(std::bind(&ThisClass::Function, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));

 

 

결론.

위와 같이 설정해두면 , "다른곳" 의 exec_func() 이 실행되면 "이곳"의 클래스 멤버함수인 Function 이 실행된다.

 

위 방식이 STL 기반 콜백함수 구현의 골격 전부이다. 이 방식으로 클래스 멤버함수도 간단히 콜백함수로 전달가능하여 콜백함수내에서 클래스 멤버에 접근이 용이하고 코드 구조도 간결해지는 큰 장점이 있다. 






posted by 갱우덩 2015. 10. 19. 22:10

C++ 에서 자주 사용거론 되는 거니까~ 넘 자세히 남기기 보다는 간단하게 남깁니다.


Class Point

{

 int x;

 int y;


 public:


 Point(int _x=0, int _y=0) : x(_x), y(_y) { } // 음~~ 이런 방법의 생성자 좋네~

 ...

 const Point& operator--()    // 전위--

 {

   --x;

   --y;

   return *this;

  }


 const Point operator--(int)    // 후위 --

 {

   Point pt(x,y);

   --x;   // 내부 구현이므로 멈버변수는 전위 -- 연산을 사용해도 무방.

   --y;   // 내부 구현이므로 멈버변수는 전위 -- 연산을 사용해도 무방.

 }


}


// 알아두면 유용하게 사용할 날이 오겠징~





posted by 갱우덩 2015. 9. 7. 18:44
요거 땜에 오늘 하루 죙일 삽질 좀 했네요~ 에거~ ㅠㅠ

string의 resize() 함수에게 속지 맙시다~ 그리고 string의 기능에 대해서 좀더 잘 알아둘 필요가 있을거 같에요

일반적으로 

char str1[100] = "111";

char str2[100] = "222";


strcat(str1, str2); 이렇게 하면


당연히


str1 의 Data는 "111222" 이렇게 된다고 생각합니다.... 당연한겁니다... 근데, STL string의 resize 라는 함수를 쓰는


순간 이렇게 동작하지 않게 됩니다.


strcat 함수 같은 경우 보면, 문자들을 붙여주는 기능을 하는 기준이 NULL 문자를 제외한 문자들 간의 연결입니다.


그런데, string은 그렇지 않더군요. 내부 적으로 size, capacity를 운영하는 string에서는 size 숫자 값에 따라 append


+= 함수의 결과가 달라 지더군요.. 이렇게 설명하면 당연히 무슨소리야~ 하겠죠~ 그래서. example!!!!


string1 str1 = "aaa";

string str2 = "bbb";


이라고 합니다. 일반적으로


str1 += str2; 


이 결과는 str1 == "aaabbb" 입니다.


그런데, 


str1.resize(50);


str1 += str2;


요렇게 하면, "aaabbb" 일거 같지만, 결과는 "aaa\0\0\0\0......bbb"가 됩니다. 


str1.append(str2);


요거 마찬가지 입니다. resize() 함수에 대해서 msdn이나 다른거 보면 간단하게 그냥 buffer 량을 늘리는게 아니라


실제 data 량을 입력숫자 만큼 늘려 주는 거라고 하는데, 이게 늘게 되면 사용자가 늘린 buffer 량 만큼입력된 data가


NULL 문자라고 해도 문자처리에서 반드시 추가적으로 인식되어 처리되더군요~ 그래서 몇시간 동안 삽질... resize() 함수로


강제로 strlen() 같은 걸로 길이 알아 내어서 다시 줄여줬죠~ ㅠㅠ. 이런거 보면 MFC CString이 더 나은듯~


예전에도 한번 이거 때문에 고생한거 같은데~ 또다시한번 당한듯한 기분~ 몇년 시간이 지나면 까먹기 마련인데~


에고~~ Blog에 남겨나 놓자~


resize 쓸일 없다구요??? 나도 그런줄만 알았네요~ 일하다보면 쓸일 생깁니다. ㅠㅠ.


***. VS Debug모드로 확인하시면 도움 많이 됩니다. 그럼~