2015-01-27 3 views
0

클래스의 변수 인 객체에 액세스하는 데 문제가 있습니다. 다음과 같이 상속 관계는 같습니다클래스 변수에 대한 액세스

#include "X.h" 

class Y 
{ 
    X object; 

public: 
    X & getObject(); 
}; 

그런 다음 다른 파일/클래스 :

#include "Y.h" 

class Z : public Y 
{ 
    X object2; 
public: 
    X & getObject2(); 
}; 

그리고 객체에 대한 포인터의 벡터를 가지고 마지막 클래스입니다. 내가 object 변수에 접근하려면

#include "Z.h" 

class XYZ 
{ 
    vector<Y*> cont; //contains objects of class type Z and Y 
}; 

, 단순히

cont[index]->getObject(); 

쓰기 그러나 object2에 접근 할 수있는 방법이 없다, 컴파일러는 심지어 getObject2()과 같은 방법을 볼 수 없습니다 . 나는 나의 설명이 명확하지 않다고 생각하지만, 어쨌든 나는 당신이 나를 도울 것을 희망한다.

+0

다른 모든 것들을 제외하고 멤버 변수에 대한 비 const 참조를 전달하는 것은 나쁜 생각입니다. 왜냐하면 클래스가 내부 상태에 대한 제어를 잃어 버렸기 때문입니다. * 제어가 객체 지향 소프트웨어를 작성하는 전체 개념입니다. 첫 번째 장소. – DevSolar

+3

getObject2는 파생 클래스의 함수이며 부모 클래스에 대한 포인터를 저장합니다. 솔루션은 http://www.learncpp.com/cpp-tutorial/121-pointers-and-references-to-the-base-class-of-derived-objects/를 참조하십시오. – Chiel

+0

@Chiel 코드의 주석은 벡터에 * both * 유형의 객체가 있음을 분명하게 설명합니다. – davmac

답변

1

첫 번째 문제는 getObject2 메서드를 호출하는지 여부를 결정합니다. 코드의 주석에 따르면 벡터에 두 가지 유형의 객체가 모두 포함되어 있으므로 어떤 특정한 객체가 이고 어떤 객체가 Y이 아닌지 어떻게 확인할 수 있습니까? Y 인 경우 getObject2 메서드를 사용할 수 없으므로 호출하지 마십시오.

몇 가지 옵션이 있습니다. 여기에 그들 중 일부는 다음과 같습니다

  • 하나의 솔루션은 두 가지 유형에 대한 두 개의 벡터를 사용하는 것입니다

    vector<Y*> conty; 
    vector<Z*> contz; 
    

    그러나이 서로 다른 개체 유형 사이의 순서를 유지하지 않습니다. 이것이 문제가되는지 아닌지는 당신의 목적에 달려 있습니다.

    (Z *)(cont[index])->getObject2(); 
    

    ...하지만 당신이 반대 할 뾰족한-의 실제 유형을 알고있는 경우에만이 작업을 수행 할 수 있습니다 -

  • 또 다른 해결책은 원하는 형식에 포인터를 캐스팅하는 것입니다.

    Z *z = dynamic_cast<Z *>(cont[index]); 
    if (z != nullptr) { 
        z.getObject2(); 
    } 
    
  • 는 또 다른 솔루션은 기본 클래스, YgetObject2을 추가하고이 Z에서 재정의 할 수 있도록 가상 만드는 것입니다 : 당신이 확실하지 않은 경우 dynamic_cast를 사용할 수 있습니다. Y에 구현하면 nullptr 만 반환하면됩니다. 반환 유형을 getObject2으로 변경해야 참조가 아닌 포인터가 반환됩니다. 최고 옵션

    class Y 
    { 
        X object; 
    
    public: 
        X & getObject(); 
        virtual X * getObject2(); 
    }; 
    

는 당신의 정확한 요구 사항에 따라 달라집니다. 당신이 시도하려는 것은 object2()를 호출하는 정말 경우

0

, 당신은 Z*을 입력하는 dynamic_cast으로 시도 할 수 있습니다. documentation에는 사용 방법에 대한 전체 설명이 있습니다 (예 :: 당신은 Y 형의 객체에 대한 포인터를 전달하는 경우는

Z* p_z = dinamic_cast<Z*> (cont[index]) 
if (p_z) 
    std::cout << p_z->getObject2(); 
0

contY*의 벡터 임) NULL 포인터를 반환 실패합니다. 이는 해당 멤버가 Y 클래스에 정의 된 API 만 노출 함을 의미합니다. getObject2()은 해당 하위 항목에서만 정의됩니다. 벡터의 멤버가 실제로 Z의 인스턴스 인 경우에도 Y 유형의 인스턴스로 액세스되는 한 Y의 인터페이스 만 사용할 수 있습니다.

당신이 세 가지 중 하나를 수행 할 필요가 사용할 수 getObject2()을 원하는 경우 : 확인
1. Y
3. getObject2() 기능을 완전히 Y
2. 이동에 가상 getObject2() 방법을 추가 contvector<Z*>

1

가상 기능이 필요한 것 같습니다. 귀하의 코드는 방식으로 변경 될 수 있습니다 :

#include "X.h" 

class Y 
{ 
    X object; 

public: 
    virtual X & getObject() 
    { 
     return object; 
    } 

}; 

과 :

#include "Y.h" 

    class Z : public Y 
    { 
     X object2; 
    public: 
     virtual X & getObject() 
     { 
      return object2; 
     } 
    }; 

를 그래서 일부 기업의 가상 테이블에 보면이 런타임에

cont[index]->getObject(); 

의 통화에서, 어느 것이 cont [index]에있는 포인터. Y 객체에 대한 포인터이면 Y 클래스의 getObject()가 호출되고 Z 객체에 대한 포인터 인 경우 Z 클래스의 getObject()가 호출됩니다.

+0

나는 이것이 질문을 다루지 않는다고 생각한다. OP는'Z' 객체를 가지고있는 경우에 첫번째 객체와 두 객체 모두에 접근 할 수 있기를 원합니다 (명시 적이 지 않지만 함축되어 있습니다). – davmac

관련 문제