2014-09-18 2 views
0

우리는 기본 클래스가 .....표준 : : shared_ptr의 클래스 공장 C++

class Node 
{ 
    public: 
     std::string Name; 
     Node(){}; 
     ~Node(){}; 
} 

필터노드의 파생 클래스입니다. 필터은 'filterId'속성을 가지고 있으며 생성자가 노드 .Name = 'Filter'로 채워지는 것을 제외하고는 동일한 노드입니다.

class Filter: public Node 
{ 
    public: 
     int filterId; 
     Filter() : Node() 
     { 
     Name="Filter"; 
     } 
} 

나는 문자열

이 링크를 CodeProject의 해당 공장에 코드를 찾아주세요을 통과 할 때 std::shared_ptr<Node>을 반환하는 ClassFactory 있습니다.

http://www.codeproject.com/Articles/567242/AplusC-b-bplusObjectplusFactory.

코드가 필터을 인스턴스화하는 것으로 보이지만, 노드을 반환합니다. 즉 Object slicing.

std::shared_ptr<Node> n = std::make_shared(Node); // As expected, doesn't not have filter ID and node.Name is blank. 
std::shared_ptr<Filter> f = std::make_shared(Filter); // As expected, has filterID and node.Name is 'Filter'. 

지금 내가 실제로 클래스 공장에서 요청 내용에 따라 표준 : : shared_ptr의 (필터)를 포함 할 수있다 표준 : : shared_ptr의 (노드)의 배열을 처리합니다.

std::shared_ptr<Node> nf = std::make_shared(Filter);  // Error. Does not have filterId, but does have **Node**.Name='Filter'. 

나는 더 간단한 경우를 시도해 보았습니다. ..... 그리고 같은 문제가 있습니다.

Node n = Node(); 
Filter f = Filter(); 
Node nf =Filter(); // Error, nf does not have a filterID, but it's Name field is set to 'Filter'. 

여기서 내가 뭘 잘못하고 있니? 노드은 모든 파생 클래스의 기본 클래스입니다. 노드을 수락하는 함수가있을 경우 필터을 보내고 filterId를 사용할 수 있어야합니다.

포인터는 이러한 상황에서 도움이 될 것을 권장하지만, shared_ptr은 사물이 얻는 것처럼 뾰족하다.

+0

부스트가 있습니다 shared_dynamic_cast – thomas

답변

0

기본 클래스에 대한 포인터 나 참조 방법이있는 경우 기본 클래스 API가 노출하는 것만 액세스 할 수 있습니다. (그렇지 않으면 예를 들어 false,0, 아마도 ㄱ boost::optional<int>을 반환 함수 또는 쌍 true,filterId 사용할 수 있음) 또는

    • 기본 인터페이스에 추가 : 당신이 filterId에 액세스하려면, 당신도 할 필요가

      std::dynamic_pointer_castFilter 유형으로 볼 수 있으면 반환 된 포인터가 부울 컨텍스트에서 true 인 경우이를 사용하여 filterId에 액세스 할 수 있습니다.

  • 1

    Node에는 파생 클래스가 정의 할 수있는 추가 데이터 멤버 및 함수에 대한 지식이 없습니다. 따라서 filterId에 액세스하려면 shared_ptr<Filter>을 가져와야합니다. 이 작업을 수행하려면 std::dynamic_pointer_cast을 사용하십시오.

    Live demo

    std::shared_ptr<Node> n = ... 
    auto f = std::dynamic_pointer_cast<Filter>(n); 
    
    if(f) { 
        // The managed object is a Filter 
        std::cout << f->filter_id << '\n'; 
    } 
    
    그리고 당신은 n 항상이 Filter (또는 Filter에서 파생 뭔가), 대신 std::static_pointer_cast을 사용할 수 있습니다 포함되어 있는지 알고 있다면.

    +0

    그래서 노드와 필터가 섞인 벡터가있는 경우이를 캐스팅해야 할 대상을 어떻게 추적 할 수 있습니까? – WebSight

    +0

    @ user2723463 처음에는'static_pointer_cast'를 쓰려고했지만 대신에'dynamic_pointer_cast'를 사용하도록 내 답변을 업데이트했습니다. 후자는 귀하의 질문에 대답합니다. 'dynamic_pointer_cast'를'Node'에서'Filter'로하려고하면, 결과로 나오는'shared_ptr'은 비게됩니다. – Praetorian

    관련 문제