파생 템플릿 클래스에 대한 기본 클래스 포인터를 포함하는 클래스에 대한 할당 연산자 및 복사 생성자

크리스티안 그레 거슨

긴 제목에 대해 사과드립니다. 내가 호출하는 클래스에 대한 할당 연산자와 복사 생성자를 작성하려고합니다 Store.

의 목적은 에서 추가 / 검색 할 수있는로 Store식별되는 다른 구조 (예 : 정수, 부동 소수점) std::string를 보유하는 것 Store입니다. 이것은 구현된다 std::map와, std::string지도의 '값'로지도에서 '키'와 같은 특정 구조.

Store 다음과 같이 정의됩니다.

    class Store {

    public:

      Store() {}

      template <class T>
      const T& get(const std::string& key) const;

      template <class T>
      void put(const std::string& key, const T& value, const bool& overwrite = false);

    private:

      std::map<std::string,FieldBase*> m_data;

    };

여기서는 FieldBase다음과 같이 정의됩니다.

    class FieldBase {

    public:

      FieldBase() {}
      virtual ~FieldBase() {}

    }

FieldBasecalled 에서 파생 된 클래스 Field는 다음과 같이 정의됩니다.

    template <class T>
    class Field : public FieldBase {

    public:

      Field(const T& value) : m_value(value) {}

      template <class U>
      Field(const Field<U>& other) : m_value( U(other.m_value) ) {}

      template <class U>
      Field& operator=(const Field<U>& other) 
      { 
        m_value = U(other.m_value);
        return *this;
      }

      virtual ~Field() {}

      const T& get() const { return m_value ; }

     private:

       T m_value;

    };

Store추가 및 검색 기능은 아래에 정의되어 있습니다. 검색하려면 다음을 사용합니다 Store::get().

    template <class T>
    const T& Store::get(const std::string& key) const
    {

      std::map<std::string,FieldBase*>::const_iterator it = m_data.find(key);

      if ( it == m_data.end() ) {
        std::cout << "Field with name " << key <<" doesn't exist!" << std::endl;
        throw 0;
      }

      Field<T>* field = dynamic_cast<Field<T>*>(it->second);
      if ( field == 0 ) {
        std::cout << "Field with name " << key << " doesn't have correct type!" << std::endl;
        throw 0;
      }

      return field->get();

    }

추가하려면 Store::put()

    template <class T>
    void Store::put(const std::string& key, const T& value, const bool& overwrite)
    {

      std::map<std::string,FieldBase*>::iterator it = m_data.find(key);

      if ( it != m_data.end() ) {
        if ( ! overwrite ) {
          std::cout << "Field with name " << key << " doesn't exist!" << std::endl;
          throw 0;
        }
        else {
          delete it->second;
          it->second = 0;
        }
      }

      Field<T>* field = new Field<T>(value);
      m_data[key] = field;

    }

그래서 클래스와 그 상호 작용을 설명하고 마침내 질문에 도달했습니다.

복사 생성자와 할당 연산자는 어떻게 찾아야 Store합니까?

분명히 std::map<std::string,FieldBase*>객체를 딥 복사하여 대상 맵을 반복 하고 어떻게 든 채워야하지만 내 문제는 FieldFieldBase포인터 아래에 숨어있는 유형을 결정하는 방법을 모른다는 것입니다 .

    // How should these be implemented ???
    Store::Store(const Store& other); 
    Store& Store::operator=(const Store& other);

어떤 도움이라도 대단히 감사합니다.

브랜든 콘

복제 패턴을 봐야합니다.

http://en.wikipedia.org/wiki/Cloning_ (프로그래밍)

가장 많이 파생 된 유형 (Field)에 정의 된 FieldBase에 순수 추상 멤버 함수를 추가하는 것입니다.

그래서:

virtual FieldBase* clone() const = 0; //! This goes in FieldBase

FieldBase* clone() const { return new Field<T>(m_value); } //! This goes in Field

그런 다음 복사 생성자에서 맵을 반복하고 기본 값을 복제 한 다음 새 인스턴스의 맵에 삽입합니다.

이 같은:

Store(const Store& other)
{
    typedef std::map<std::string, FieldBase*> StoreMap;
    for (StoreMap::const_iterator it(other.m_data.begin()); it != other.m_data.end(); ++it)
        m_data.insert(std::make_pair(it->first, it->second->clone()));
}

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Related 관련 기사

뜨겁다태그

보관