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 를 입력후 재부팅 한다