2014-04-06 6 views
1

의 캐스팅 포인터가 아닌 인스턴스는 내가 클래스 A를하고C++ 사용자 정의 클래스

class A 
{ 
public: 
    A(){}; 
} 

class B : public A 
{ 
public: 
    B(int value){ foo = value }; 
    int foo; 
} 

B가있는 int foo에있는의 서브 클래스 서브 클래스 B를 가지고 말할 수 있습니다.

std::vector<A> mylist; 
B myB(5); //Create a new instance of class B 
mylist.push_back(myB); //Add b to my vector of A. 

가 지금은 myList에의 요소에 액세스하고 B를 입력하고 'foo는'검색 캐스팅 입력하십시오 : 좋아

이제 다음 내가 말할 수 있습니다. 다음은 합법적입니까?

B *instance = (B *)&mylist[0]; 

내 프로젝트에이 일을 시도했지만 내가 foo는의 값을 출력한다면 그것은 잘못된 것입니다 :

std::cout<<instance->foo<<std::endl; // This does not give me 5. It gives me a garbage number. 

문제점은 그렇게하지 사실에서 유래한다 C++에서 비 포인터를 변환하는 적절한 방법을 알고 있어야합니다.

+0

'좋아 지금은 할 말을 할 수는 다음과 같이하십시오. 당신이 그렇게해서는 안되기 때문에 나머지 질문은 논점이됩니다. – PaulMcKenzie

+0

^그럼 비 포인터를 던져 올바른 방법을 알아 내려고 애 쓰고있어 ... – user1855952

+0

가능한 복제본 [C++에서 슬라이싱 문제가 무엇입니까?] (http://stackoverflow.com/questions/274626/) what-is-the-slicing-problem-in-c) –

답변

2

이것은 C++에서 슬라이싱 문제의 일반적인 예입니다.

쉽게 피할 수 있도록 포인터를 벡터에 저장해야합니다. 원시 포인터를 처리하고 싶지 않으면 스마트 포인터를 사용하십시오.

+0

슬라이싱이란 무엇입니까? 거기에 포인터없이 이것을 할 수있는 방법이 있습니까? – user1855952

+0

@lizusek : 형식 필드가 어떻게 도움이 될까요? 슬라이싱은 밀 때 발생합니다. – lpapp

+0

@ user1855952 스마트 포인터 살펴보기 – 4pie0

2

mylist.push_back(myB)이라고 쓰면 슬라이스이 발생합니다. mylist에는 A 개체가 저장됩니다. 따라서 발생하는 것은 BA으로 변환되어 B이 아닌 A에있는 모든 것을 잃어 버리게됩니다. A 만 저장됩니다. 잃어버린 조각은 검색 할 수 없습니다.

그것은 일을하는 것과 같습니다 다형성 동작을하기 위해

B myB(5); 
A a(myB); 

, 당신은, 즉 A *A는 다형성 클래스가 될 수 있도록, 또한 포인터에 의해 개체를 참조 할 필요가있다.

A (가상 소멸자가 좋습니다)에 하나 이상의 가상 함수를 추가하고 벡터 저장소 포인터를 가져야합니다. 예 :

std::vector< A* > mylist; 
mylist.push_back(new myB(5)); 
B *instance = dynamic_cast<B *>(mylist[0]); 

이제이 코드는 정상이지만 새로 입력 한 메모리를 삭제할 때는 매우주의해야합니다. 이를 해결하기 위해 참조 카운트 된 shared_ptr이 있습니다. 나는 작동하는 것 같다 다음 테스트 케이스 만든 (면책 조항 - 나는 스마트 포인터와 다형성의 전문가 아니에요을, 그래서 여기에 몰래 오류가없는 희망)

#include <iostream> 
#include <memory> 
#include <vector> 

class A 
{ 
public: 
    A(){}; 
    virtual ~A() {} 
}; 

class B : public A 
{ 
public: 
    B(int value): foo(value) {} 
    int foo; 
    ~B() { std::cout << "Destructor B(" << foo << ")" << std::endl; } 
}; 

int main() 
{ 
    std::vector< std::shared_ptr<A> > mylist; 

// Test the polymorphic behaviour 
// mylist.push_back(std::make_shared<A>()); 

// create directly into container 
    mylist.push_back(std::make_shared<B>(5)); 

// via pointer 
    B *temp_b = new B(6); 
    mylist.push_back(std::shared_ptr<B>(temp_b)); 

    std::shared_ptr<B> instance = std::dynamic_pointer_cast<B>(mylist[0]); 
    if (!instance) 
     std::cout << "Item was not a B" << std::endl; 
    else 
     std::cout << instance->foo << std::endl; 
}