2012-06-26 2 views
2

소스 코드없이 C++ 라이브러리에서 클래스를 확장 할 수 있습니까? 헤더를 사용하면 상속을 사용할 수 있습니다. 나는 C++을 배우는 중이고 이론에 익숙해 있습니다. 나는 이것을 시험 할 것이지만 나는 어떻게해야할지 모른다.C++에서 라이브러리 확장

답변

3

예, 클래스의 선언으로 충분합니다.

나머지 코드는 라이브러리에 연결할 때 선택됩니다.

+0

그렇다면 부모 클래스의 메서드를 재정의하지 말아야합니까? –

+0

아니요, 문제가되지 않습니다. 컴파일러와 링커는 어떤 함수가 기본 클래스에 속하고 어떤 클래스가 파생 클래스에 속하는지 파악할 것입니다. 일반적으로 클래스를 사용하기 위해 멤버 함수의 소스가 필요하지 않습니다. .cpp 파일 (나중에 쓰여지기도합니다)이나 라이브러리에있을 수 있습니다. –

2

예 표준 C++ 라이브러리에서 클래스를 확장 할 수 있습니다. 헤더 파일로 충분합니다.

몇 가지 예 :

  • 사용자 정의 예외
  • 귀하의 응용 프로그램에서 사용자 정의 스트림을 만들 수있는 확장 스트림 라이브러리를 만들 std::exception 클래스를 확장

그러나 당신이 알아야 할 한 가지입니다하지 virtual destructor이없는 클래스를 확장하십시오. 예를 들면, std::string

편집 std::vector 있습니다 : 난 그냥 그냥 헤더 파일이 해당 클래스에서 상속에 대한 충분한 가진이 주제 Extending the C++ Standard Library by inheritance?

+0

그렇다면'std :: true_type'과'std :: false_type'은 둘 다''std :: integral_constant'에서 파생 된 이유는 무엇이든 가상 소멸자가 없기 때문입니까? STL 디자이너는 OOP 기본 규칙을 인식하지 못 했습니까? 아니면 OOP 전용 도구가 아닌 상속입니까? –

1

의 다른 SO 질문을 발견했다.
컴파일러가 타입의 정의를 검색 및 언어 correctness.This을위한 프로그램이 오브젝트 파일을 생성 검사

  • 편집 :
    C++ 프로그램은 두 단계에 내장되어 있습니다.
  • 연결
    컴파일 된 개체 파일은 함께 연결되어 실행 파일을 만듭니다.

그러니 당신이 헤더 파일 (컴파일에 필요한) 및 라이브러리 ( 연결에 필요한 ) 당신은 클래스에서 파생 할 수 있습니다로.
그러나 클래스가 실제로 상속을위한 것인지를주의해야합니다.
예 : 비 소위 virtual 소멸자 클래스가있는 경우 해당 클래스는 상속을위한 것이 아닙니다. 모든 표준 라이브러리 컨테이너 클래스와 동일합니다.

간단히 말해 클래스의 인터페이스 만 있으면 파생에 충분하지만 클래스의 구현 및 디자인 의미가 중요한 역할을합니다.

+0

감사! 소스 코드가없는 경우 클래스의 상속 여부를 어떻게 결정할 수 있습니까? 또한 소스 코드가 없으면 메서드를 재정의하지 말아야합니까? –

+0

@DavidLee,이 질문을 참조하십시오 - http://stackoverflow.com/questions/1073958/extending-the-c-standard-library-by-inheritance – Sanish

+1

@DavidLee 클래스에 헤더에 가상 소멸자가 있는지 확인할 수 있습니다 파일. 그러나 일반적으로 문서에 의존해야 할 수도 있습니다. 의심스러운 경우 상속하지 마십시오. – juanchopanza

4

짧은 대답 예, 확실히 할 수 있습니다.

긴 대답 : 경고 : 다음 텍스트는 아이들에게 민감한 OOP의 integralists에 손상을 줄 수 있습니다.만약 당신이 그런 느낌이 들거나 그런 식으로 남아 있다면,이 대답에서 벗어나십시오. 내 모든 것과 내 인생이 더 쉬워 질 것입니다.

STL 코드는 일반 C++ 코드에 불과합니다. 헤더와 라이브러리를 사용하면 코드와 정확히 같을 수 있습니다. STL 작성자는 여러분처럼 프로그래머입니다. 그것들은 컴파일러와 관련하여 특별한 의미가 없습니다. Thay에는 그것에 대해 어떤 초강대국도 없다. 그들은 마치 자신이하는 것처럼 화장실에 앉아 당신이하는 일을 정확하게 수행합니다. 그들을 지나치게 잘못 쓰지 마십시오.

STL 코드는 자신이 작성한 코드와 완전히 똑같은 규칙을 따릅니다. 즉, 가상 포인터 인 경우 항상 오버라이드 된 포인터가 호출됩니다. 항상 가상 포인터 인 경우 항상 참조 포인터의 정적 유형에 따라 가상 포인터가 아닌 경우에만 호출됩니다 다른 모든 C++ 코드와 마찬가지입니다. 그 이상도 이하도 아닌.

중요한 것은 STL 이름 규칙 및 의미를 존중하는 디자인 문제를 피하는 것이 아니므로 코드를 계속 사용하면 10 년 후에 코드를 읽거나 특정 결정을 더 이상 기억하지 않아도 사람의 기대를 혼동하지 않습니다. .

예를 들어 std::exception::what()을 덮어 쓰면 설명적인 영구 C 문자열 (STL 설명서 에서처럼)이 반환되고 예기치 않은 다른 퍼지 동작이 추가되지 않아야합니다.

또한, 스트림 또는 스트리밍 사업자 재정의 전체 디자인 (cosidering 할 놈이야 당신이 정말로 스트림 아니면 그냥 streambuffer을 무시하거나 그냥 고취 로케일에 특정 를 추가해야 할 ?) : 즉, "클래스"가 아니라 주변 세계와 어떻게 작동하는지 제대로 이해하기 위해 모든 "세계"의 디자인을 연구합니다.

가장 중요한 논점 중 하나는 컨테이너와 가상 소멸자가없는 모든 것입니다.

내 의견 인에 대한 소음 단순히 당신이 그것을에 saddle을 배치 이유만으로 cowhorse되었다 기대하지 않는다 : 과도한 팽창은 "고전적인 OOP 규칙 그나마 '무슨 가상 소멸자가없는 것은 유도" .

암기 적으로 std :: string으로 변환 할 수있는 std :: string과 동일한 인터페이스를 사용하여 문자 시퀀스를 관리하는 클래스가 필요하다면 (그게 정말로 필요합니다) 더 많은 것이 있습니다. 두 가지 방법 :

  • 좋은 좋은 여자, 할 std:string을 포함하고 다시 일을 할 모든 112 : 그들을 호출하는 것보다 더 아무것도하지 않는 당신은 여전히 ​​처녀 와서 확인 기능 방법 (예 그들은 더 많은 100입니다) 다른 훌륭한 좋은 소년 프로그래머 코드와 결혼하거나 ...
  • 이것은 약 30 년이 걸리며 40 세가 될 위험이 있음을 알게 된 후 처녀 더 좋은 소년 프로그래머는 더 이상 관심이없고, 더 실용적이며, 처녀성을 희생하고 std::string을 파생시킵니다. 당신이 풀어 줄 유일한 것은 통합 주의자와 결혼 할 가능성입니다. 그리고 당신은 심지어 반드시 문제가 아니라는 것을 발견 할 수 있습니다 : 당신은 그로 인해 죽을 위험으로부터 멀리 떨어져 있습니다!

당신이 알아서해야 할 유일한 것은 std::string 당신의 유도와 같은 그것을 만들 MOT 것 다형성하지, 너무 기대하지 않고 std::string* 또는 yourstring를 참조 std::string&되는 것은 소멸자 포함하여 메소드를 호출하는 것입니다, 그건 다른 방법마다 특별한 존경이 아닙니다. 그것은 단지 똑같은 규칙을 따른다. 하지만 ... 음, 암시 적 변환 연산자를 포함하고 작성하면 정확하게 결과를 얻을 수 있습니다.

규칙은 쉽습니다. 소멸자를 가상으로 만들지 말고 OOP 용으로 설계되지 않은 무언가로 작업하기 위해 "OOP 대체 원리"를 가장하지 말고 모든 것이 올바르게 수행됩니다. 그들은 여전히 ​​단지를 포함하는 100 + 표준 : : 문자열 방법을 재 작성하는 동안 pacem 영원한 잠에 requemscant, 당신의 코드가 작동 integralist 모든 OOP와

.

+1

화장실 은유에 대한 엄지 손가락 최대 –

관련 문제