태그 보관물: stl

stl

std :: vector에서 상속하지 않아야합니다. 직접 멤버가되기를

좋아, 이것은 고백하기가 정말로 어렵지만, 나는 지금부터 물려받을 강한 유혹을 받는다 std::vector.

벡터에 대해 약 10 개의 사용자 정의 알고리즘이 필요하며 벡터의 직접 멤버가되기를 바랍니다. 그러나 당연히 나는 나머지 std::vector인터페이스 를 원합니다 . 법을 준수하는 시민으로서의 첫 번째 아이디어 std::vectorMyVector수업에 회원 을 두는 것이 었습니다 . 그러나 모든 std :: vector의 인터페이스를 수동으로 제공해야합니다. 입력하기에 너무 많습니다. 다음으로 개인 상속에 대해 생각했기 때문에 메서드를 제공하는 대신 using std::vector::member공개 섹션에 여러 개를 작성했습니다 . 실제로 너무 지루합니다.

그리고 여기에, 나는 실제로 공개적으로 상속 할 수 있다고 생각 std::vector하지만이 클래스를 다형성으로 사용해서는 안된다는 경고를 문서에 제공합니다. 나는 대부분의 개발자들이 이것이 다형성으로 사용되어서는 안된다는 것을 이해하기에 충분히 유능하다고 생각합니다.

내 결정이 절대적으로 정당하지 않습니까? 그렇다면 왜 그렇습니까? 추가 멤버가 실제로 멤버이지만 벡터의 모든 인터페이스를 다시 입력하지는 않는 대안을 제공 할 수 있습니까 ? 나는 그것을 의심하지만, 가능하다면 나는 행복 할 것이다.

또한 일부 바보는 다음과 같은 것을 쓸 수 있다는 사실을 제외하고

std::vector<int>* p  = new MyVector

MyVector를 사용할 때 다른 현실적인 위험이 있습니까? 사실이라고 말하면 벡터에 대한 포인터를 취하는 함수를 상상하는 것과 같은 것을 버립니다 …

글쎄, 나는 나의 사건을 진술했다. 나는 죄를 지었다. 이제 나를 용서할지 아닌지는 당신에게 달려 있습니다 🙂



답변

사실,의 ​​상속 상속에는 아무런 문제가 없습니다 std::vector. 이것이 필요하면 그렇게하십시오.

정말로 필요한 경우에만 그렇게하는 것이 좋습니다 . 자유 기능으로 원하는 것을 수행 할 수없는 경우에만 (예 : 상태를 유지해야 함).

문제는 MyVector새로운 실체라는 것입니다. 그것은 새로운 C ++ 개발자가 그것을 사용하기 전에 지옥이 무엇인지 알아야한다는 것을 의미합니다. 차이 무엇 std::vectorMyVector? 어느 쪽이 여기저기서 사용하는 것이 더 낫습니까? 내가 이동해야하는 경우 std::vectorMyVector? 그냥 사용할 수 swap()있습니까?

더 좋아 보이는 것을 만들기 위해 새로운 엔티티를 만들지 마십시오. 이러한 실체들 (특히, 그런 것들)은 진공 상태에서 살지 않을 것입니다. 그들은 끊임없이 증가하는 엔트로피와 혼합 환경에서 살 것입니다.


답변

전체 STL은 알고리즘과 컨테이너가 분리 되도록 설계되었습니다 .

이것은 const iterators, random access iterators 등과 같은 다른 유형의 반복자 개념으로 이어졌습니다.

따라서이 컨벤션을 수락 하고 작업중 인 컨테이너가 무엇인지 신경 쓰지 않는 방식으로 알고리즘을 설계 하는 것이 좋습니다. 그리고 수행 해야하는 특정 유형의 반복자 만 필요합니다. 작업.

또한 Jeff Attwood의 좋은 말로 안내해 드리겠습니다 .


답변

std::vector공개적으로 상속받지 않는 주된 이유 는 가상 소멸자가 없기 때문에 자손의 다형 적 사용을 효과적으로 방지 할 수 있습니다. 특히,하는 수 없습니다 에 파생 객체 (파생 클래스에 구성원을 추가하지 않는 경우에도)에서 실제로 점, 아직 컴파일러는 일반적으로 대한 경고를 표시 할 수 없습니다.deletestd::vector<T>*

이러한 조건에서는 개인 상속이 허용됩니다. 따라서 아래에 표시된 것처럼 개인 상속을 사용하고 부모로부터 필요한 메소드를 전달하는 것이 좋습니다.

class AdVector: private std::vector<double>
{
    typedef double T;
    typedef std::vector<double> vector;
public:
    using vector::push_back;
    using vector::operator[];
    using vector::begin;
    using vector::end;
    AdVector operator*(const AdVector & ) const;
    AdVector operator+(const AdVector & ) const;
    AdVector();
    virtual ~AdVector();
};

먼저 대부분의 응답자가 지적한 것처럼 알고리즘을 리팩토링하여 작동하는 컨테이너 유형을 추상화하고 무료 템플릿 기능으로 남겨 두어야합니다. 이것은 일반적으로 알고리즘이 컨테이너 대신 인수로 반복자 쌍을 허용하도록하여 수행됩니다.


답변

당신이 이것을 고려하고 있다면, 당신은 이미 당신의 사무실에서 언어 교육자들을 죽였다. 그들을 방해하지 않는 이유는 무엇입니까?

struct MyVector
{
   std::vector<Thingy> v;  // public!
   void func1( ... ) ; // and so on
}

그러면 실수로 MyVector 클래스를 업 캐스팅 할 때 발생할 수있는 모든 실수를 피할 수 있으며 조금만 추가하면 모든 벡터 작업에 계속 액세스 할 수 있습니다 .v.


답변

무엇을 성취하기를 바라고 있습니까? 일부 기능 만 제공합니까?

이를 수행하는 C ++ 관용적 방법은 기능을 구현하는 일부 무료 기능을 작성하는 것입니다. 실제로 std :: vector가 필요하지 않을 가능성이 있습니다.실제로 구현하는 기능에 대해 . 이는 std :: vector에서 상속하려고하면 실제로 재사용 가능성을 잃고 있음을 의미합니다.

표준 라이브러리와 헤더를보고 작동 방식에 대해 묵상 할 것을 강력히 권합니다.


답변

나는 거의 100 %의 맹목적으로 따라야 할 규칙이 거의 없다고 생각합니다. 당신이 그것에 대해 많은 생각을했던 것처럼 들리며, 이것이 갈 길이라고 확신합니다. 따라서 누군가 이렇게하지 말아야 할 특별한 이유가 없다면 계획을 진행해야한다고 생각합니다.


답변

자신의 방식으로 정의 의 숨겨진 세부 사항을 처리하기 때문에 또는 다른 클래스 대신에 해당 클래스의 객체를 사용해야하는 이데올로기 적 이유가없는 한, std::vector다른 방식으로 작동하는 클래스를 만들지 않는 한 상속 할 이유가 없습니다. 의 것. 그러나 C ++에서 표준 작성자는 상속 된 클래스가 벡터를 특정 방식으로 향상시키기 위해 활용할 수있는 인터페이스 (보호 멤버의 형태)를 제공하지 않았습니다 . 실제로, 그들은 확장을 필요로하거나 추가 구현을 미세 조정할 필요가 있는 특정 측면 을 생각할 방법이 없었기 때문에 어떤 목적 으로든 그러한 인터페이스를 제공 할 필요가 없었습니다.std::vectorstd::vectorstd::vectorstd::vector

두 번째 옵션의 이유 std::vector는 다형성이 아니기 때문에 단지 이데올로기 일 수 있으며 , 그렇지 않으면 std::vector공개 상속을 통해 또는 공개 멤버십을 통해 공개 인터페이스를 노출하는지 여부에 차이가 없습니다 . (자유로운 기능을 피할 수 있도록 객체의 상태를 유지해야한다고 가정하십시오). 소리가 적고 이데올로기 적 관점에서 볼 때 std::vectors는 일종의 “간단한 아이디어”인 것처럼 보이며 , 대신 가능한 다른 클래스의 객체 형태의 복잡성은 이데올로기 적으로 사용하지 않습니다.