문제

스택-합금 객체와 함께 이기종 벡터에 물체를 저장합니다

안녕하십니까,

CA1, CA2 등으로 파생 된 추상 클래스 CA가 있다고 가정 해 봅시다.

이 파생 된 유형의 객체를 클래스 CB에 넣은 벡터에 넣고 싶습니다. 다형성을 올바르게 얻으려면 포인터의 벡터를 저장해야합니다.

class CB
{
    std::vector <CA*> v;
};

이제 다음과 같은 주요 기능이 있다고 말합니다.

int main()
{
    CB b;
    CA1 a1;
    CA2 a2;
    b.Store( a1 );
    b.Store( a2 );
}

방법을 어떻게 작성합니까? void CB::Store(const CA&) 간단한 방식으로 저장된 객체는 원래 물체가 파괴 될 때 살아남습니다 (위의 간단한 예에서는 발생하지 않음).

내 문제는 벡터에서 흡입을 복사하기 전에 힙의 객체를 먼저 복사해야한다는 것입니다. 그러나 파생 된 유형의 객체를 어떻게 만들 수 있습니까? 물론, 나는 RTTI를 사용하고 가능한 모든 유형을 검색하고 포인터를 만들고 할당하고, 벡터로 밀기 전에 할당 된 공간에 물체를 (적절한 캐스팅) 복사 할 수 있습니다. 그러나 이것은 꽤 복잡해 보입니다.

더 간단한 방법이 있습니까?

(그리고 메인에서 동적 할당을 사용하지 않고!)

도움이 되었습니까?

해결책

일반적으로 복제 기능을 제공합니다.

struct CA
{
    virtual CA *clone(void) const = 0;
    virtual ~CA() {} // And so on for base classes.
}

struct CA1 : public CA
{
    virtual CA *clone(void) const
    {
        return new CA1(*this);
    }
}

struct CA2 : public CA
{
    virtual CA *clone(void) const
    {
        return new CA2(*this);
    }
}

이것을 a라고합니다 가상 생성자, 런타임에 객체의 사본을 구성 할 수 있습니다.

void CB::Store(const CA& pObject)
{
    CA *cloned = pObject.clone();
}

사용 고려해야합니다 부스트 포인터 컨테이너 도서관. 코드는 다음과 같습니다.

boost::ptr_vector<CA> objects;

void CB::Store(const CA& pObject)
{
    objects.push_back(pObject->clone());
}

그리고 지금 당신은 메모리를 직접 관리 할 필요가 없습니다. 도서관은 또한 복제 기능을 존중하며 객체의 사본을 만들 때 호출합니다. 여기 튜토리얼.

다른 팁

파생 클래스가 구현할 추상 클래스에서 클론 () 함수가 필요한 것 같습니다.

class CA
{
   public:
   virtual ~CA() {}
   virtual CA* clone() const = 0;
}

class CA1 : public CA
{ 
    public:
    virtual CA *clone() const
    {
       return new CA1(*this);
    }
};

가능성은 논증의 유형에 따라 매장을 템플릿하는 것입니다.

class CB
{
public:
    template<class T>
    void Store(const T& t)
    {
         v.push_back(new T(t));
    }

private:
    std::vector <CA*> v;
};

그러나 경고 : 다른 사람들이 게시 한 "Clone ()"솔루션과 달리 슬라이스가 발생하기 쉽습니다. 예를 들어, 이것은 잘 작동합니다.

CB b;
CA1 a1;
CA2 a2;
b.Store(a1);
b.Store(a2);

그러나 이것은 다음과 같습니다.

CA1 a1;
CA* a = &a1;
b.Store(*a); //Ouch! this creates a new CA, not a CA1

보호 된 사본 CTOR를 CA에 제공하면 그러한 오용을 방지합니다. 그러나 CA1을 더 하위 클래스하면 문제가 다시 발생합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top