2016-07-12 2 views
1

C 언어에서 "private", "protected"와 같은 액세스 지정자를 구현할 수있는 방법이 있습니까? 인터넷에서 특정 기능 내에서만 사용할 수있는 기능을 만들기 위해 "정적"및 "ifdefs"를 사용하는 방법에 대한 해결책을 찾았습니다.C 언어로 데이터 숨기기 액세스 지정자 구현

이외에도 C++ 클래스에서 개인 및 보호 된 액세스 지정자를 사용하는 것과 동일한 C 구현이 있습니까?

+1

C

  • https://en.wikipedia.org/wiki/Opaque_pointer
  • 은 튜링 완료됩니다. 문제는 노력할 가치가 있고 코드가 여전히 유지 보수 가능한지 여부입니다. C++을 원하면 C가 아니라 C++을 사용하십시오. 이들은 다른 언어입니다. (지옥, 왜 아무도 SQL에서 인라인 어셈블러를 요구하지 않습니까?) – Olaf

    +1

    @Olaf C에서 OOP를 수행하는 것은 완전히 합리적이며 모든 복잡한 C 프로젝트에서 가장 좋은 방법이라고 할 수 있습니다. 단점은 더 많은 상용구 코드가 필요하며 컴파일러가 C++ 컴파일러가 동등한 코드를 탐지하거나 허용하지 않는 오류의 일부를 감지 할 수 없다는 점입니다. 또한 C++ 스타일의 RAII는 사용할 수 없습니다. 보너스는 프로그래머가 코드에서 일어나는 일을 완벽하게 제어 할 수 있으며 암시 적 코드 실행 파일 (예외 나 암시 적 생성자 및 소멸자가 없음)이없고 vtable도 프로그래머가 직접 제어 할 수 있다는 것입니다. – hyde

    +0

    @hyde : OOP는 C++에서 구현 한 방식이 아닙니다. 정보 숨김은 OOP의 핵심 요소는 아닙니다 (C++ 또는 Java의 부분 OOP와 달리 전체 OOP 인 Python과 같은 다른 언어 참조). 내가 C에서 OOP를 할 수 없거나하지 말아야한다는 것을 어디에서 지적합니까? 명시되지 않은 의미를 읽지 마십시오! 그러나 특정 기능을 직접 지원하는 언어를 사용하는 것이 말을 넘어서서 말을 타는 것보다 낫다는 점이 분명해야합니다. – Olaf

    답변

    4

    C에는 사용자 정의 이름 공간이나 액세스 지정자가 없습니다. 전 처리기를 (ab) 사용을 배제하기 때문에 "클래스"의 사적 부분에 액세스하려고하는 컴파일러 오류를 얻는 유일한 방법은 "개인"항목을 노출하는 .h 파일을 가지지 않는 것입니다. 그것들은 여전히 ​​"private"개별 .h 파일 (모듈이나 라이브러리의 .c 파일에 포함되어 있지만 응용 프로그램 코드에는 포함되지 않음) 또는 #ifdef 뒤에 숨겨 질 수 있습니다 ("개인" 부분품).

    일을 숨기는 일반적인 방법 중 하나는 불투명 한 구조체 AKA 불투명 포인터를 사용하는 것입니다. 이러한 접근 방식에서 모듈이나 라이브러리 외부의 코드는 구조체에 대한 포인터 만 갖지만 구조체 정의는 없습니다. 그런 다음 모듈에서 제공하는 기능을 사용하여 인스턴스를 가져와 액세스하고 마지막으로 릴리스합니다.

    이 방법을 사용하면 public 인터페이스를 쉽게 얻을 수 있습니다. public .h 파일에서 제공하는 함수와 정의가있는 public support struct. 개인 인터페이스는 전체 구조체 정의가 표시되는 코드와 공용 .h 파일에없는 함수입니다.

    보호 된 액세스는 상속을 의미합니다. 상속은 일반적으로 C++과 매우 다르게 작동합니다. 수동으로 C로 구현하면이 대답에서 다루기에는 너무 광범위합니다. 이것에 가장 가까운 것은 여러 개의 "공개"액세스 레벨을 제공하는 여러 개의 .h 파일을 갖는 것입니다. 그런 다음 프로그래머가 문제를 일으키지 않아야합니다.

    이 접근법에 대한 좋은 점은 구조체가 변경되면 모듈을 사용하는 다른 코드를 수정 (또는 다시 컴파일) 할 필요가 없다는 것입니다. 종종 struct는 공용체 일 수도 있고 모듈의 함수는 실제 유형을 기반으로 분기 할 것이며 코드를 사용하는 코드에서 모두 볼 수 있습니다. 또 다른 좋은 점은 모듈이 구조체 생성을 제어 할 수 있기 때문에 예를 들어 구조체 풀을 갖고 응용 프로그램 코드에서 보이지 않는 힙 사용을 피할 수 있다는 것입니다. 한 가지 단점은 인라인 함수를 사용할 수 없다는 것입니다.h 파일은 구조체 정의가 필요합니다. 여기서는 숨기려고합니다), 성능이 중요한 경우 좋은 컴파일러 최적화를 방지합니다.

    예제 (이 답변을 작성 테스트되지 않은 코드) :

    module.h에 : 참조

    // ...other standard header file stuff ... 
    
    // forward declaration of struct 
    struct module_data; 
    
    // "constructor" function 
    struct module_data *module_initialize_data(int value); 
    
    // modification function 
    int module_update_data(struct module_data *data, int adjust); 
    
    // "destructor" function 
    void module_release(struct module_data *data); 
    

    module.c

    #include "module.h" 
    
    // struct definition only in the .c file 
    struct module_data { 
        int value; 
    }; 
    
    struct module_data *module_initialize_data(int value) { 
        struct module_data *data = malloc(sizeof(*data)); 
        data->value = value; 
        return data; 
    } 
    
    int module_update_data(struct module_data *data, int adjust) { 
        data->value += adjust; 
        return data->value; 
    } 
    
    void module_release(struct module_data *data) { 
        free(data); 
    } 
    

    관련 위키 백과 링크 :

    +0

    C에는 네임 스페이스가 있습니다! 단지 사용자 정의 네임 스페이스가 없습니다. 귀하의 접근 방식은 OP가 요구하는 것을 허용하지 않습니다. 그것을 구현하는 것은 훨씬 더 복잡합니다 (그리고 난센스). – Olaf

    +0

    @Olaf 범위를 의미합니까, 아니면 무엇을 의미합니까? – hyde

    +0

    네임 스페이스와 범위를 잘 구분할 수 있습니다. 표준을 읽으십시오. (범위와 이름 공간도 차별화됩니다). – Olaf

    5

    C에는 액세스 지정자가 없습니다. 호출자에게서 뭔가를 숨기는 유일한 방법은 헤더에 선언을 제공하지 않는 것입니다.

    extern int visibleVariable; 
    void visibleFunction(); 
    

    int visibleVariable; 
    static int invisibleVariable; 
    void visibleFunction() { 
        ... 
    } 
    static void invisibleFunction() { 
        ... 
    } 
    

    당신은 또한 그것을 배치하여 struct의 정의를 숨길 수 있습니다 myapi.c

    myapi.h :

    당신은 번역 단위에서 정적 만들 수 있습니다 구현 파일에서. 이 방법을 사용하면 구조체의 모든 필드가 번역 단위에 비공개가됩니다. 이 방법의 단점은 API 사용자가 struct 유형의 변수를 선언 할 수 없으므로 포인터를 통해 struct을 처리해야한다는 것입니다.

    C에는 상속 개념이 없으므로 protected 액세스 권한이 없습니다.

    +0

    흠, 구현에서'int i;'도 정적입니다. 정적이라는 뜻입니다. 그러나 OP가 원하는 것은 실제로 보이지 않습니다. – Olaf

    +2

    @Olaf OP가 원하는 것의 일부인 것처럼 보입니다. 그는 더 많은 것을 원합니다. – dasblinkenlight

    +0

    그는 부분적으로 보이지 않는 멤버가있는 하나의'struct '를 원한다. 재미있게도 C++이 실제로 숨기지 않는다면 도달하기가 더 어려워집니다. – Olaf