2014-11-21 4 views
0

Я пытаюсь объявить vector<Item> как частный член другого класса Inventory, но он дает мне ошибку, говоря, что Item не входит в сферу действия. Оба класса объявляются в одном файле. Я не знаю, как изменить масштаб, на который он смотрит, или что бы вы ни делали, чтобы заставить его работать.C++ как объявить вектор объектов как член класса

Вот код, чтобы сделать абсолютно ясно, что я пытаюсь сделать.

class Inventory { 
public: 

private: 
    vector<Item> inventory; 
}; 

class Item { 
public: 
    void SetName(string nm) 
     { name = nm; }; 
    void SetQuantity(int qnty) 
     { quantity = qnty; }; 
    void SetPrice(int pric) 
     { price = pric; }; 
    virtual void Print() 
     { cout << name << " " << quantity << " for $" << price 
      << endl; }; 
    virtual ~Item() 
     { return; }; 
protected: 
    string name; 
    int quantity; 
    int price; 
}; 
+2

Поместите декларацию позиции до публикации инвентаря. – Borgleader

+1

Вам нужно определить 'Item' * before *, вы используете его как аргумент' vector'. –

+0

Спасибо, честно говоря, не думаю, что в ближайшее время я подумал бы об этом. – Eegxeta

ответ

3

Item должно быть определено до его использования в качестве аргумента шаблона.

Технически вы можете уйти с объявлением вперед в определенных контекстах, но чтобы сэкономить время и разочарование в обучении точным правилам, проще просто убедиться, что вы определили его в первую очередь.

В целом, порядок объявлений важен. Если вы используете тип в декларации другого типа, использованный тип должен быть уже. Исключения из этого правила включают использование указателем и ссылкой, которые требуют только прямого объявления.

+1

Как правило, для работы над декларацией о переходе я спрашиваю себя, должен ли компилятор знать размер или макет объекта, например. зарезервировать место в рамках другого класса. Если нет, тогда есть хорошая возможность прокрутки вперед. В этом случае вектор, вероятно, не должен знать макет элемента, пока вы не попытаетесь добавить или получить доступ к нему. Быстрый тест показал декларацию, работающую по крайней мере на одном компиляторе. –

+0

@MarkRansom является правильным. Я собирался добавить некоторые детали к моему ответу в терминах 'sizeof', но он по существу сделал это. Я не был уверен, нужно ли для «std :: vector» полное определение или просто объявление вперед и не может проверять в то время, но в целом оно будет зависеть от конкретного определения шаблона, о котором идет речь, независимо от того, требуется ли оно во время использования аргумента шаблона. Например, 'boost :: shared_ptr' специально говорит, что они * не нуждаются в полном определении, но' std :: auto_ptr' делает. – b4hand

1

Определите элемент первым, а затем инвентарь.

class Item { 

public: 
    void SetName(string nm) 
     { name = nm; }; 
    void SetQuantity(int qnty) 
     { quantity = qnty; }; 
    void SetPrice(int pric) 
     { price = pric; }; 
    virtual void Print() 
     { cout << name << " " << quantity << " for $" << price 
      << endl; }; 
    virtual ~Item() 
     { return; }; 
protected: 
    string name; 
    int quantity; 
    int price; 
}; 

class Inventory { 
public: 

private: 
    vector<Item> inventory; 
}; 
1

Как std::vector<Item> тип в своем собственном праве, он должен быть объявлен после декларации в Item класса.

(Это похоже на правило, которое для class Child : public Base должно содержать надпись Base).

A форвардная декларация is не недостаточно.

В одном направлении это использовать std::vector<std::shared<Item>> (вектор интеллектуальных указателей), но это, конечно, изменяет структуру вектора. В этом случае передняя декларация составляет.

Смежные вопросы