2017-05-11 8 views
1

자료 클래스와 프로덕션 코드로 많은 파생 클래스 (예 : DerivedX)가 있습니다. 해당 클래스를 건드리지 않고 테스트 목적으로 내부 데이터를 조작하기 위해 Base에서 파생되는 클래스 BaseExt 클래스를 만듭니다. 여기 좋은 이유와 함께 형제 자매 수업을하고 있습니까?

+-----------+   +-----------+ 
| Base  + <- - - - - | BaseExt | 
+-----------+   +-----------+ 
    /|\ 
    | 
+-----------+ 
| DerivedX + 
+-----------+ 

그것은 나에게 직관적으로 작동하는 코드 예제

 class Base { 
     public: 
     int data() const { return _data; } 
     protected: 
     Base() = default; 
     virtual ~Base() = default; 
     int _data; 
     }; 

     class Derived1 : public Base { 
     }; 

     class BaseExt : public Base { 
     public: 
     void inject_data(int data) { _data = data; } 
     }; 

입니다.

std::shared_ptr<Base> p = std::make_shared<Derived1>(); 
    auto d1 = p->data(); // 0 
    std::static_pointer_cast<BaseExt, Base>(p)->inject_data(10); 
    auto d2 = p->data(); // 10 

기준 : 나는 그러나 나는 그런을 많이 가지고, 내가 같은 일을 할 Derived1을 확장 할 수 물론

내 생산 코드 (즉, 자료 및 DerivedX)을 변경하지 않으 파생 된 클래스는 단순한 작업에 너무 많은 코드를 추가합니다.

문제는

  • 입니다 그것은이 사용 사례에 대한 형제 클래스로 캐스팅하는 것이 합리적이다?
  • 안전하게 만드는 방법은 무엇입니까? (형제 클래스의 예를 들면, 어떤 속성 없음) 더 좋은
  • 과 (수정 자료 및 DereivedX 클래스 제외) 간결 솔루션 템플릿에 대한
+0

더 안전한 방법은이를위한'친구 '기능을 만드는 것이다. – Zefick

+0

왜 직관적입니까, Derived1 유형의 인스턴스를 다른 유형의 BaseExt로 캐스팅합니다. BaseExt에 데이터 멤버가 있다면 어떨까요? – marcinj

+0

@ Base 클래스에서 @Zefick 친구 기능을 사용 하시겠습니까? Base와 DereivedX 클래스를 수정하는 것은 마지막 옵션이 될 것입니다. – elgcom

답변

1

무엇입니까? 또한

template<typename T> 
struct TestableDerived : T { 

    inject_data(int data) { 
     _data = data; 
    } 

    static std::shared_ptr<Base> createAndInjectData(int data) { 
     std::shared_ptr<TestableDerived<T>> ptr = std::make_shared<TestableDerived<T>>(); 
     ptr->inject_data(data); 
     return ptr; 
    } 
} 

, 당신이 당신의 소스를 변경 할 준비가 있다면 각 파생 클래스는 거의 Base (즉 class DerivedX : public virtual Base가), 나는 방금 중 '별도의 방법을 얻을 수있는 다중 상속이 혼합 수 있다고 생각에서 상속 등 테스트 '(나는 이것을 테스트하지 않았다) :

struct BaseExt : virtual Base { 
    void inject_data(int data) { _data = data; } 
} 

template<typename T> 
struct TestDerived<T> : virtual T, virtual BaseExt {} 

void doSomeTesting() { 
    std::shared_ptr<TestDerived<DerivedX>> p1 = std::make_shared<TestDerived<DerivedX>>(); 
    std::shared_ptr<DerivedX> p2 = p1; 
    std::shared_ptr<BaseExt> p3 = p1; 

    assert(p1->data()==0); 
    assert(p2->data()==0); 
    assert(p3->data()==0); 

    p3->inject_data(10); 

    assert(p1->data()==10); 
    assert(p2->data()==10); 
    assert(p3->data()==10); 
} 
관련 문제