2014-07-20 3 views
3

나는 그 클래스 AB 더 ..이컴파일 타임에 일정한 크기의 배열 ..하지만 파생 클래스에서 만

class A : public O 
{ 
    static const int _nbItems = 3; 
    ... 
}; 

class B : public O 
{ 
    static const int _nbItems_mine_mine = 7800; 
    ... 
}; 

... 

그들은 추상적 부모 클래스 O 모든 inheritate하는 는 .. Item의 수집을 관리하고 그들이 원하는대로 아이들이 놀러 못하게하는 방법 알고

class O 
{ 
private: 

    // The kids won't be able to access this structure directly for it is carefully updated 
    Item _items[size];   

    // (I mean.. *truly*, look :) 
    void update() // called by the clock 
    { 
     for(int i(0); i < size; ++i) /* things involving */ _items[i] /*, its environment etc.*/ 
    }; 

protected: 

    // They may set their items this way only: 
    void setItemNo(int id, BuildInformation const& buildInfo) 
    { 
     /* 
     * check whether or not the item has already been added.. 
     * perform everything that must be done to welcome a new item.. 
     * well.. 'so many things the kids do not need to be aware of. 
     */ 

     // and then: 
     _items[id] = Item(buildInfo); 

    }; 

    // .. retrieve information about the current state of their items this way only: 
    SomeInformation getItemState(int id) const {return _items[id].currentState();}; 

    // .. and eventually change some of their properties this way only: 
    void setItemProperty(int id, Property const& newProperty) 
    { 
    /* checks, updates, eventual repercussions on other items and the environment */ 
    _items[id].setProperty(newProperty); 
    }; 
}; 

O::_items에 대한 구조로 사용하여 스택에 할당 된 Item이 모두에 할당 된 구조로 사용할 수 있습니까? 크기가 궁극적으로 컴파일 시간에 알려지기 때문에 가능한 것이어야합니다.

그것을 anoter 방법을 넣어 : 어떻게 자신의 길을 찾을 *nbItems* 정보가 아직 정의되지 않은 O에, 컴파일러 그들은 여전히 ​​문자 상수 알고하자 패션에 O::size까지 할 수 있을까?


추신 : O가 기록되는 시간, 나는 분명히 언젠가는있을 수있는 모든 가능한 파생 클래스를 인식하지입니다. 중간 파생 클래스 다음

class O 
{ 
    virtual size_t size() const = 0; 
    virtual Item * data() const = 0; 

    void update() 
    { 
     for (Item * p = data(), * e = p + size(); p != e; ++p) 
     { 
      // use *p 
     } 
    } 

public: 
    virtual ~O() {} 
}; 

: 다음

template <size_t N> class OWithArray : public O 
{ 
public: 
    static size_t const nItems = N; 
private: 
    Item items[N]; 
    virtual size_t size() const { return nItems; } 
    virtual Item * data() const { return items; } 
}; 

그리고는 모두 실제 파생 클래스가 중간 클래스에서 파생 :

+1

'O'가'size'에서 매개 변수화 된 템플릿 클래스가 될 수없는 이유가 있습니까? –

+1

'O' 템플릿을 만듭니다. '템플릿 클래스 O {Item _item [size]; }'이면 파생 클래스는'O <3>'또는'O <7800>'에서 파생 될 수 있습니다. –

+0

@CharlesBailey : 오, 그렇지 않을 수도 있습니다! 이걸 더 생각해 봅시다. :) –

답변

2

당신은 배열하지 않고 기본 클래스 O을 가질 수

class A : public OWithArray<3> 
{ 
    // ... 
}; 
+0

달콤한, 왜 T.C와 Charles Bailey가 제안한대로'O'를 직접 템플릿으로 만들지 않습니까? –

+1

@ Iago-lito : 글쎄, 당신은 추상적 클래스에서 'O'라고 말했습니다. (예에서는 그렇지 않습니다.) 더 자세한 정보가 없으면'O'가 클래스 템플릿이 아닌 실제 클래스가 될지 여부가 명확하지 않습니다. –

+1

@ Iago-lito'O'를 직접 템플릿으로 만들면'O <3>'과'O <7800> '이 서로 다른 유형이므로'A '와'B '는 공통 기본 클래스를 갖지 않습니다. 이것은 공통 기본 클래스를 제공합니다. –

1
class O { 
    private: 
    Item* items; 
    unsigned int number_of_items 

    protected: 
    O (Item* itemsstorage, unsigned int n_items) 
    : items (itemsstorage), number_of_items (n_items) { ... } 

    // you'll probably need something like the following 
    // make it private rather than using "= delete" prior to C++11 
    O & operator = (const O &) = delete; 
    O (const O &) = delete; 
    O (O &&) = delete; 

    public: 
    virtual ~O() { } 
} 

class A : public O { 
    private: 
    enum { howManyItems = 3 }; 
    Item allMyItems [howManyItems]; 

    public: 
    A() : O (allMyItems, howManyItems) { } 
} 

또는을 템플리트 A가 더 유연하게 : 당신이 다형의 ('의 O으로 S'의 A을 치료하는 경우을

template<unsigned int N> 
class A : public O { 
    private: 
    Item allMyItems [N]; 

    public: 
    A() : O (allMyItems, N) { } 
} 

참고 클래스 O에서 가상 소멸자를 필요로하는 것은 의미 : 당신은 확실히,하지 않는 한 당신은 절대적으로 100 % 확신하지 못합니다!) !!!!

+1

또한 할당 연산자를 제공해야합니다. –

+0

당신은 복사와 이동을 막고'O '를 할당해야합니다. – JohnB

+0

그래도이 방법으로'A'는'Item's로 원하는대로 할 수 있습니다. 그렇지 않습니까? 'allMyItems [0] .setProperty ("fancyOne")'을 호출하여 전체 과정을 망칠 수있는 방법은 없습니다. –

관련 문제