2016년 6월 2일 목요일

const iterator 를 리턴하는 stl 자료구조에서 const를 푸는법

map 류의 힙형 자료구조는 정렬된 상태를 유지하기에 iterator가 const값만을 리턴한다
따라서 부득이하게 iteraotr 값을 바꿔야할 경우
템플릿 함수를 하나 만들고 아래처럼 활용한다.

template  T & unconst(const T & x)
{
   return const_cast(x);
};
 multimap myMap;
 multimap::iteraotr it;
.
.
.
unconst(*it);

2015년 1월 28일 수요일

user defined conversion ,void pointer ,Smart Pointer에서의 쓰임

출처 : http://www.informit.com/articles/article.aspx?p=31529&seqNum=7
함수 인자에서 형변환과 유저 타입 형변환 연산자가 어떻게 작용하는지 설명하는 좋은 글이라 생각한다
something* 타입 형변환을 SmartPtr 포인터에 operator something* 타입으로 정의 선언 해 놓으면
그 함수를 fun(sp)시 그 연산자 호출 된다 암시적 형변환을 통해 (something*)으로의 형변환 연산자를 찾게되고 다시
포인터 타입임으로 암시적으로 void* 로 변환된다..

7.7 Implicit Conversion to Raw Pointer Types

Consider this code:
void Fun(Something* p);
...
SmartPtr<Something> 
     sp(new Something);
Fun(sp); // OK or error?
Should this code compile or not? Following the “maximum compatibility” line of thought, the answer is yes.
Technically, it is very simple to render the previous code compilable by introducing a user-defined conversion:
template <class T>
class SmartPtr
{
public:
   operator T*() // user-defined conversion to T*
   {
      return pointee_;
   }
   ...
};
However, this is not the end of the story.
User-defined conversions in C++ have an interesting history. Back in the 1980s, when user-defined conversions were introduced, most programmers considered them a great invention. User-defined conversions promised a more unified type system, expressive semantics, and the ability to define new types that were indistinguishable from built-in ones. With time, however, user-defined conversions revealed themselves as awkward and potentially dangerous. They might become dangerous especially when they expose handles to internal data (Meyers 1998a, Item 29), which is precisely the case with theoperator T* in the previous code. That's why you should think carefully before allowing automatic conversions for the smart pointers you design.
One potential danger comes inherently from giving the user unattended access to the raw pointer that the smart pointer wraps. Passing the raw pointer around defeats the inner workings of the smart pointer. Once unleashed from the confines of its wrapper, the raw pointer can easily become a threat to program sanity again, just as it was before smart pointers were introduced.
Another danger is that user-defined conversions pop up unexpectedly, even when you don't need them. Consider the following code:
SmartPtr<Something> sp;
...
// A gross semantic error
// However, it goes undetected at compile time
delete sp;
The compiler matches operator delete with the user-defined conversion to T*. At runtime, operator T*is called, and delete is applied to its result. This is certainly not what you want to do to a smart pointer, because it is supposed to manage ownership itself. An extra unwitting delete call throws out the window all the careful ownership management that the smart pointer performs under the covers.
There are quite a few ways to prevent the delete call from compiling. Some of them are very ingenious (Meyers 1996). One that's very effective and easy to implement is to make the call to deleteintentionally ambiguous. You can achieve this by providing two automatic conversions to types that are susceptible to a call to delete. One type is T* itself, and the other can be void*.
template <class T>
class SmartPtr
{
public:
   operator T*() // User-defined conversion to T*
   {
      return pointee_;
   }
   operator void*() // Added conversion to void*
   {
      return pointee_;
   }
   ...
};
A call to delete against such a smart pointer object is ambiguous. The compiler cannot decide which conversion to apply, and the trick above exploits this indecision to good advantage.
Don't forget that disabling the delete operator was only a part of the issue. Whether to provide an automatic conversion to a raw pointer remains an important decision in implementing a smart pointer. It's too dangerous just to let it in, yet too convenient to rule it out. The final SmartPtr implementation will give you a choice about that.
However, forbidding implicit conversion does not necessarily eliminate all access to the raw pointer; it is often necessary to gain such access. Therefore, all smart pointers do provide explicit access to their wrapped pointer via a call to a function:
void Fun(Something* p);
...
SmartPtr<Something> sp;
Fun(GetImpl(sp)); // OK, explicit conversion always allowed
It's not a matter of whether you can get to the wrapped pointer; it's how easy it is. This may seem like a minor difference, but it's actually very important. An implicit conversion happens without the programmer or the maintainer noticing or even knowing it. An explicit conversion—as is the call to GetImpl—passes through the mind, the understanding, and the fingers of the programmer and remains written in the code for everybody to see it.
Implicit conversion from the smart pointer type to the raw pointer type is desirable, but sometimes dangerous. SmartPtr provides this implicit conversion as a choice. The default is on the safe side—no implicit conversions. Explicit access is always available through the GetImpl function.

2015년 1월 27일 화요일

c++ static 함수의 접근 범위


class foo {
public:
    int a;
    // static member function "get_a" ...
    static int get_a(foo *f) {
        // ... accesses public non-static data member "a"
        return f->a;
    }
};
위의 예제와 같이 static 함수가 클래스의 멤버로 속해 있다면 객체를 받아와서 객체의 논스테틱 멤버에 접근이 가능하다

class foo {
public:
    int a;
    // static member function "get_a" ...
   
};

 static int get_a(foo *f) {
        // ... accesses public non-static data member "a"
        return f->a;
    }
단 아래의 경우는 스태틱 함수가 클래스의 멤버가 아니므로 객체의 인스턴스를 받아온다 하더라도 NonStatic 멤버에 접근할수 없다 출처: http://stackoverflow.com/questions/1871379/c-static-member-functions-and-their-scope

MFC 에서의 클래스위자드에서는 ON_MESSAGE는 자동화 해주지 않는다..

Note
ClassWizard does not support entering ON_MESSAGE handler routines from the ClassWizard user interface: you must manually enter them from the Visual C++ editor. Once entered, ClassWizard will parse these entries and allow you to browse them just like any other message-map entries.

MSDN 발췌: POSEMESSAGE SENDMESSAGE 를 처리하는 루틴은 
클래스 위자드에서 지원하지 않는다.
따라서 수동으로 추가하여야 한다

c++ 디폴트 생성자와 함수 선언


class MyClass
{
   //...
   //...
};


main()
{
    MyClass my();//문제가 될 소지가 있다 c++ 컴파일러 파서에서는 함수의 선언인지 
                 //디폴트 생성자인지 처리해야하는 모호함의 문제가 있다 
                 //컴파일러에 따라 경고,혹은 error 처리 된다
}

2015년 1월 6일 화요일

윈도우 8.1 IDE 로 설치후 AHCI 로 바꾸는 방법

출처:
http://pricklytech.wordpress.com/2014/02/04/windows-8-1-enabling-ahci-after-installing-windows/

1. 시작 버튼에 마우스 오른쪽 클릭후 메뉴에 관리자 권한으로 명령 프롬프트를 실행한다

2. bcdedit /set {current} safeboot minimal 라고 입력 한다

3. 후에 재부팅 하고 부팅 전 바이오스에 들어가(일반적으로 DEL,F9,F8 버튼을 누르면 들어간다) IDE 모드를 AHCI로 변경한다

4. 윈도가 안전모드로 부팅되면 마찬가지로 관리자 권한 명령 프롬프트를 실행한다

5. bcdedit /deletevalue {current} safeboot 를 입력후 재부팅 한다


2014년 12월 23일 화요일

매개변수에서 const 위치

1. const 가 * 의 왼쪽에 위치 시 포인터가 가르키는 대상이 상수.. char  const * a
  a[0]='a' 불가
2. const 가 * 의 오른쪽에 위치 시 포인터 변수가 상수 char * const  a
    a = "abcd " 불가

타입명과 const 위치는 바뀌어도 뜻은  똑같다.
void fun (const char *a)
void fun (char const *a)

2014년 12월 18일 목요일

포인터

포인터는 변수의 타입이며 무엇이든 그 컴퓨터의 주소를 담을수 있다.

포인터 형을 일반 지역변수에서 선언하던, 전역에서 선언하던 함수의 인자에서 선언하던 해당 컴퓨터/컴파일러의 주소범위 내의 사이즈 타입의 변수에 그 포인터 원형의 주소가 담기게 된다.

애초에 int a char b 처럼 변수의 이름은 컴파일시 심볼테이블에 의해 실 주소로 치환이 된다.
이것을 이해하면 포인터의 주소개념을 더 명확히 할수 있다.

거기서 오프셋 연산이나 역참조를 통한 직접접근이 가능하게 되는것이다. 포인터가 담기게되는 스택형 변수와 힙 포인터를 착각하게 되는것을 주의하자.

char * pc  -> char 타입이 담겨있는 주소. 즉 pc의 실제 메모리 주소를 가르킨다.

char ** ppc -> char * 타입이 담겨있는 주소. 역시 ppc 주소를 가르키며 그 안에는 당연히 char* 타입의 데이터가 담겨있어야 한다.



2014년 12월 9일 화요일

C 에서의 extern

사용되고 있는 변수가 다른 파일에서 정의(기억장소가 할당되도록 함) 되었다면
그 외부변수를 사용하기 위해 extern 으로 '선언' 하고 사용하여야 한다
보통 한 파일에서  아래와 같은 방식으로 사용한다

file1.c
int gInt = 1; //정의와 선언

file1.h
extern int gInt;

file2.c
#include "file1.h"
gInt = 2;
단 배열의 extern 은 그 크기를 명사하여야 하나
extern 에서는 생략이 가능하다
즉 아래의 표현은 동일하다

extern int array[10];
extern int array[]; 

2014년 12월 7일 일요일

콜렉션 FIND predicate 함수를 사용하는 3가지 방법

콜렉션 개체

public class person
{
    public int Anni { get; set; }
    public string Nome { get; set; }
    public person(int anni, string nome)
    {
        this.Anni = anni;
        this.Nome = nome;
    }
}
무명 메소드 (델리게이트 사용)

//I assume I have a non-empty list List agenda = new List();
/* .. load objects from DataBase .. */

//I create a simple search criteria string personToBeSearched = "mario";
person mario = agenda.Find(delegate(person p) { return p.Nome == personToBeSearched; });
람다 식 사용

//I assume I have a non-empty list List agenda = new List();
/* .. load objects from DataBase .. */

//I create a simple search criteria string personToBeSearched = "mario";
person mario = agenda.Find(p => p.Nome == personToBeSearched;);
델리게이트 사용

private static bool findTeen(person p)
{
    if (p.Anni < 18)
        return true;
    return false;
}

List BlockBuster_GameOnly = agenda.findAll(findTeen);