2012-04-25 7 views
-1

나는 boost::ptr_vector을 사용하고 있지만, 이는 표준 std::vector에도 적용된다고 생각합니다. 내가 polymophically boost::ptr_vector 계층에 개체에 대한 포인터를 배치 시도하고 내가 Object에서 상속 Entity이 라인을 작성하는 가지고있다포인터의 다형성

Object * newObject = new Entity(param1, param2); // then I attempt to add it to the ptr_vector 

하지만 난 볼 수있는 프로그램 (비주얼 스튜디오 2010)을 어기면 보유하고있는 것은 쓰레기에서 결코 방향 전환되지 않으며 쓰레기가 열리고 있습니다. 코드를 단계별로 실행하고 매개 변수화 된 생성자를 입력 한 다음 올바른 논리 단계를 따릅니다.

나는 무엇이 잘못 될지 불확실합니다. 이 다형성 동작이 작동하려면 부모 또는 자식에 특정 멤버 함수가 있어야합니다 (현재 모든 자식에는 유형에 고유 한 매개 변수화 된 생성자가 있고 다형 상호 작용 메소드와 함께 소멸자가 있습니다). 할당 연산자가 있어야합니까, 아니면 Object 클래스의 생성자를 사용해야합니까?

연산자 new에 대한 호출이 개체로 확인되지 않고 다른 것으로 해결되지만 VS2010에서 오류가 발생하지 않는 것으로 보입니다.


편집 : 일어날 일에 대한 설명. 객체를 결정 case/switch를 사용

생성 한 객체를 생성하는

포인터 구조에 추가하고, 새로 할당 할 (직사각형/비 들쭉날쭉) 2D std::vector // I 단계별

문제는 카메라 스터드 관리자 부재 boost::ptr_vector

으로 푸시 그 포인터의 참조를

일어나는 곳이다 생각 io 2010 포인터를 만들기 위해 줄을 끊고 포인터를보고 boost::ptr_vectorpush_back() 줄에 새 (다형성)와 줄을 할당합니다. 임시 포인터 값이 생성되고 생성자로 이동하면 해당 생성자에 대한 모든 논리적 단계를 따르고 생성자가 완료되면 스택이 생성자를 호출 한 행으로 돌아갑니다. 포인터는 여전히 동일한 값입니다 (이 값은 받아 들일 수는 있지만) 객체를 보면 모든 값을 물음표 (정적으로 구성된 멤버 객체 포함)로 표시합니다. 그런 다음 푸시 백이 트리거되고 부스트 헤더에 들어가면 x 값은 동일한 정보를 표시합니다.

포인터가 만들어진 것처럼 보이고 개체의 데이터가 만들어 지지만 일단 생성자가 끝나면 실제로 부모 클래스 개체에 값을 할당하지 않습니다.이 개체는 상당히 간단해야합니다. 다형 성 행동.우려의

예를 들어 헤더 (실제 헤더는 멤버 변수를해야합니까, 그 구현은 별도의 cpp 파일에있는) :

class Object{ 
public : 
    virtual void interact(int action, Object& source){} 
    virtual void updateObject(float duration){} 
    virtual ~Object(){} 
    bool operator==(const Object& _other)const; 
    bool operator!=(const Object& _other)const; 
}; 

class Entity : public Object{ 
public: 
    Entity(Vector3 location, Type thisType, SpecialType difficulty=noSpecial); 
    ~Entity(); 
    void interact(int action, Object& source); 
    void updateObject(float duration); 
}; 

편집 : 손 나은 대상 문제에 대한 컨텍스트를 변경, 솔루션을 받으십시오

+0

벡터를 채우는 방식을 표시 할 수 있습니까? – Naveen

+0

@naveen 나는 그것과 관련 있다고 생각하지 않는다. 벡터를 채우지 만, 실제로 생성되는 객체를 가져 와서 첫 번째 위치에 포인터에 할당합니다. – gardian06

+3

이것은 아마도 어리석은 질문이지만, 경우에 따라 ... 최적화되지 않은 디버그 빌드를 디버깅하고 있습니까? 릴리즈 빌드에서는 컴파일러가 모든 중간 복사본을 건너 뛰고 포인터를 일부 레지스터에두고 벡터의 저장 공간이 될 때까지 메모리의 어느 위치에도 저장하지 않을 가능성이 높습니다. 디버거는 newObject, x 등을 보려고 할 때마다 그 레지스터의 내용을 보여줌으로써이를 처리 할 수 ​​있지만, 포인터에 대해 가비지를 표시하거나 아무것도 표시하지 않음으로써 쉽게 처리 할 수 ​​있습니다. – abarnert

답변

0

게시 한 내용에 따라 문제가 무엇인지에 대해서는 물론 문제를 해결하는 것이 어렵습니다 (가능한 경우). 그것.

아마도 실제로 작동하는 것으로 시작하여 필요한 기능을 추가하거나 예상했던 것과 다른 곳에서 작동하는 것이 좋습니다. 따라서 여기에 객체를 동적으로 생성하는 작은 샘플이 있습니다. ptr_vector에 가상 함수를 사용하여 컨테이너의 내용이 예상 한 것임을 확인한 다음 컨테이너가 범위를 벗어나게합니다. (그리고 프로세스 중에는 파괴됩니다. 객체에 포함 된 포인터에 의해 참조되는 객체).

#include "boost/ptr_container/ptr_vector.hpp" 
#include <iostream> 
#include <string> 
#include <sstream> 

class Object { 
    std::string name; 
public: 
    Object(std::string const &n) : name(n) {} 

    virtual std::ostream &write(std::ostream &os) const { 
     return os << name; 
    } 

    virtual ~Object() { std::cout << "Object being destroyed\n"; } 
}; 

class Entity : public Object { 
    int value; 
public: 
    Entity(int v, std::string name) : Object(name), value(v) {} 

    std::ostream &write(std::ostream &os) const { 
     return os << "Entity: " << value; 
    } 
    ~Entity() { std::cout << "Entity being destroyed\n"; } 
}; 

int main() { 
    boost::ptr_vector<Object> objects; 

    for (int i=0; i<10; i++) { 
     std::stringstream name; 
     name << "object: " << i; 
     if (i & 1) 
      objects.push_back(new Object(name.str())); 
     else 
      objects.push_back(new Entity(i, name.str())); 
    } 

    boost::ptr_vector<Object>::iterator pos; 
    for (pos = objects.begin(); pos != objects.end(); pos++) { 
     pos->write(std::cout); 
     std::cout << "\n"; 
    } 
    return 0; 
} 

은 적어도 나를 위해, 결과는 다음과 같다 : 그것은 가치가 무엇인지, 소멸자를 참고

Entity: 0 
object: 1 
Entity: 2 
object: 3 
Entity: 4 
object: 5 
Entity: 6 
object: 7 
Entity: 8 
object: 9 
Entity being destroyed 
Object being destroyed 
Object being destroyed 
Entity being destroyed 
Object being destroyed 
Object being destroyed 
Entity being destroyed 
Object being destroyed 
Object being destroyed 
Entity being destroyed 
Object being destroyed 
Object being destroyed 
Entity being destroyed 
Object being destroyed 
Object being destroyed 

- Object이 파괴 될 때, 단지 기본 dtor가 호출하지만 때 Entity이 파괴되면 파생 된 dtor가 호출되고 기본 dtor가 호출됩니다 (따라서 '엔티티가 파괴되었습니다'및 '오브젝트가 파괴됨'을 볼 수 있습니다).

+0

나는'boost :: prt_vector '을 호출하여'ptr_vector'를 잘못 처리 한 것이 었습니다. 마지막으로 넣은 것과 항상 동일하게 만들어졌고, 포인터가 범위를 벗어 났을 때 객체가 이미 쓰레기를 멈추었습니다. – gardian06

1

생성자가 끝나면 포인터 값이 변경되지만 문제가되지 않습니다. 처음에는 임시 포인터가 작동하고 포인터 만 할당되기 때문에 논리적입니다.

+0

을 실험하는 것이 좋지만 생성자가 호출되는 것과 같이 재 할당이 일어나지 않고 할당이 수행되지 않는 경우 – gardian06

1

Object * newObject = new Entity(param1, param2); 

후에는 새로 생성 된 객체에 newObject 가리키는 것입니다. 생성자가 인 동안은 newObject이 할당되지 않습니다. 이후에 예 : 는 push_back 방법으로 공정과 인수를 볼 수

vec.push_back(newObject); 

Entity 방법을 참조하는 가상 테이블을 갖는 Object이다. (적어도 가상 소멸자가 맞습니까?)

+0

예 가상 소멸자가 있습니다. , 그리고'push_back()'을 입력하면'x'는 동일한 가비지 포인터 값을 보여 주며, 포인터가 가리키는 값을 보면'Entity' 생성자가 대입을하더라도 물음표를 보여줍니다. 'new'는 포인터를 만들어 포인터 변수에 바로 할당해야합니까? – gardian06