2012-01-19 3 views
4

우리는 수십 년에 걸쳐 개발 된 커다란 C 코드 기반을 가지고 있습니다. 이 코드의 기능 중 하나는 함수 포인터와 의사 상속에 크게 의존한다는 것입니다. 관용구는 (here를 바와 같이)과 같이 다음과C에서 상속 : 좋음, 나쁨 또는 기타?

typedef struct twod_ { 
    double x, y; 
} twod; 

typedef struct threed_ { 
    twod super; 
    double z; 
} threed; 

threed *point_3d; 
twod *point_2d = (twod *)point3d; 

되는 점과 point_2d->xpoint_3d->x는 동일한 메모리 블록이다.

내 질문은 :

  • 이 관용구는 현대적인 생산 코드에서 여전히 인기인가? (권장되는 공개 소스 예제)
  • 이 코드에는 성능 요구 사항이 있습니다.이 관용구가 속도 및/또는 메모리 사용에 도움이됩니까?
  • 코드가 구현 된 방식 (또는 많은 코드가 부 풀림)으로 스파게티 코드와 같은 느낌이 들었습니다. 일반적으로 구현이나 이디엄에 문제가 있습니까? 또는 다른 말로하면 이상적인 세계에서이 관용구가있는 500k LOC가 빨리 이해 될까요?

당연히, "만약 문제가 해결되지 않았다면 고치지 마라."라는 명제는 계속 기억하는 것이 좋습니다. 그러나 그것은 현재 우리에게 도움이되지 않습니다. 그래서 우리는 리팩토링과 함께 더 깊이 들어가야 할 것이라고 생각합니다.

감사합니다!

+0

"twod"변수를 역 참조하려고하면 정의되지 않은 동작이 발생하지만 마지막 행을'twod * point_2d = & point3d.super; '로 바꾸면 물의 상태가 양호합니다. –

+2

관용구에 상관없이 500k LOC를 빨리 이해할 수 있다고 생각하지 않습니다. –

+0

twod * point_2d = (threed *) point3d로 생각합니다. 당신은 실제로 twod * point_2d = (twod *) point3d를 의미합니다; – MetallicPriest

답변

2

비록 그것이 다소 장황 해지기 때문에 당연히 혼란 스러울 수 있지만 물론 괜찮다고 말할 수 있습니다.

"C가있는 클래스"의 주요 오픈 소스 구현은 아마도 GTK+이며, 특히 gobject 모듈입니다.

+0

GNOME 데스크탑, GIMP (ofc GTK + 언급했듯이!), GStearmer도 GObject를 사용합니다. –

0

C에서와 거의 비슷하지만, 당신이 뭘하는지 알면 괜찮습니다. 그러나 문제는 매우 쉽게 나타날 수 있습니다. 예를 들어 배열이 threed 인 경우 twod의 배열로 전송할 수 없습니다. (이 캐스팅 된 배열의 멤버에 액세스하는 것은 정의되지 않은 동작입니다.)

1

이되지만, 컴파일러가 가변 액세스 또는 기타 이와 관련된 문제에 대해 경고하거나 말할 수는 없다는 점을 명심해야합니다 그. 때때로이 명시 적 형변환이 악조건이 될 수 있기 때문에이 메서드는 형식에 안전하지 않습니다. 예를 들어이 예제를 가지고 : 일의

typedef struct _A 
{ 
    double x, y; 
} A; 

typedef struct _B 
{ 
    A super; 
    double z; 
} B; 

typedef struct _C 
{ 
    A super; // we wanted B, but wrote A by mistake 
    double w; 
} C; 

C* c; 
B* b = (B*)c; 

// will write to C::w instead of B::z and no one will warn you about this. 
// you'll need to track this by hand after your application crashes. 
b->z = 1234; 

이 유형은 easly 땅에 비행기를 넣을 수 있습니다. :) 당신이 (캐스팅보다 더 안전) 손으로 슈퍼 포인터를 가지고있는 것처럼 성능에 대한

,이 같은 일을하고 종료됩니다 :

는 또한
A* a; 
B* b = &a->b; 

나는이 인기라고 생각하지 않습니다 요즘 (나 같은 젊은 프로그래머가 더 현대적인 컴파일러에서 프로그래밍을 성장시킨 적은 아님)

또한 C++ 컴파일러는 옵션입니까? 요즘 구조체 상속을 허용하는 최신 컴파일러 - 이런 식으로 캐스팅하는 것보다 낫다.

0

현대 생산 코드에서이 관용구가 여전히 인기가 있습니까?( 권장 오픈 소스 예제)

지금은 볼 수 있지만 다소 드뭅니다. 나는 이것을 대중적이라고 부르지 않을 것이다. C 프로그램에서 다형성을 사용하는 경우가 거의 없다.

이 코드에는 성능 요구 사항이 있습니다.이 관용구가 속도 및/또는 메모리 사용에 도움이됩니까?

확실히 3 명 멤버를 포함하는 구조체에 비해더 효율적인 코드를하지 않습니다. 최악의 경우, 유산은 코드의 효율성을 떨어 뜨립니다. 가장 좋은 방법은 특정 플랫폼 용 컴파일러 출력으로 디스 어셈블하여 직접 확인하는 것입니다.

... 구현 또는 이디엄과 관련된 문제입니까?

일반적으로 상속은 신중하게 사용해야하며, 상속을 목적으로 상속은 아무 목적없이 사용되어야합니다. 그것은 모든 OO 언어에 해당됩니다.

개인적으로, 나는이 특별한 관용구와 C에서 약간 유용한 OO 기능을 포함하려는 유사한 시도가 문제가 있다고 생각합니다. 주로 프로그램에 상당한 복잡성을 추가하기 때문입니다. 이런 것들은 "ANSI-C로 객체 지향 프로그래밍"(Axel-Tobias Schreiner, 90 년대 초에 발표 됨)이라는 책에서 설교되었습니다. 나는 개인적으로 그 책에서 대부분의 것들이 아주 끔찍한 것을 발견했다.

이상적 세계에서 500k LOC는이 관용구를 사용하면 빨리 을 이해할 수 있습니까?

이 작은 OO 관용구보다는 프로그램 구조, 파일 구조 및 코딩 표준에 훨씬 더 달려 있습니다. 물론 프로그램이 최첨단 인 경우에도 500k loc가 빨리 이해되지는 않습니다.

관련 문제