2013-04-04 2 views
38

У меня есть вектор C++. Я хочу, чтобы вектор содержал переменное количество объектов.Как создать объекты при добавлении их в вектор?

Visual Studio 2012 дает мне ошибку:

Error: type name is not allowed 

С этой C++ код:

#include <iostream> 
#include <vector> 
using namespace std; 

class testObject{ 
private: 
    int someInt; 
public: 
    testObject(int a){ someInt=a; } 
    void show() { cout<<someInt<<endl; } 
}; 

int main() 
{ 
    vector<testObject> testVector; 
    cout << "Initial size: " << testVector.size() <<endl; 

    for (int i = 0; i < 3; i++) 
     testVector.push_back(testObject(3)); 
    cout << "New size: " << testVector.size() << endl; 

    for (int j = 0; j < 3; j++) 
     testVector[ j ].show(); 

    system("pause"); 
}  

Но вот еще один пример кода, который выглядит так же, но это не работает.

void Dealer::setNumberOfPlayers(const int tNumber) 
{ 
    for (int i = 0; i < tNumber; i++) 
     vectorOfGamers.push_back(Player); // Player is a class that I created 
} 

Могу ли я создать вектор для хранения объектов Дилера, Бот и Игрока одновременно? Как мне это сделать? Как я знаю, все объекты в векторе должны быть одного типа.

+6

+1 для корректного вопроса (ваш английский неплох). – Cameron

+2

Создайте экземпляр игрока. – Arun

+0

Дублируйте, однако, ответы на оба этих вопроса можно найти легко через google или даже здесь, на SO. –

ответ

48

Чтобы ответить на первую часть вашего вопроса, вы должны создать объект типа Player, прежде чем сможете его использовать. Когда вы говорите push_back(Player), это означает «добавить игрока класс к вектору«, а не «добавить объект типа« Игрок к вектору »(это то, что вы имели в виду).

Вы можете создать объект в стеке, как это:

Player player; 
vectorOfGamers.push_back(player); // <-- name of variable, not type 

Или вы даже можете создать временный инлайн и нажать, что (он получает скопирована, когда она помещается в векторе):

vectorOfGamers.push_back(Player()); // <-- parentheses create a "temporary" 

Чтобы ответить на вторую часть, вы можете создать вектор базового типа, который позволит вам отбрасывать объекты любого подтипа; Однако, это не будет работать, как ожидалось:

vector<Gamer> gamers; 
gamers.push_back(Dealer()); // Doesn't work properly! 

, поскольку, когда объект дилера поместить в вектор, он копируется как объект Gamer - это означает, что только часть Gamer эффективно скопировано «нарезку " объект.Вы можете использовать указатели, однако, с тех пор только указатель будет скопирован, и объект никогда не нарезанный:

vector<Gamer*> gamers; 
gamers.push_back(new Dealer()); // <-- Allocate on heap with `new`, since we 
            // want the object to persist while it's 
            // pointed to 
+1

@eoLithic: он работал в первом примере, поскольку он создавал временный объект (синтаксис «тип (конструктор-аргументы)» и передавал его, несмотря на сходство в синтаксис, он имеет совсем другое значение ;-) – Cameron

+0

Благодарим вас за помощь. Думаю, мы можем закрыть эту тему. – eoLithic

+0

Можно ли сделать последнюю часть * без * выделения ее на кучу (и все еще иметь полиморфизм)? – mtahmed

5

Вопрос 1:

vectorOfGamers.push_back(Player) 

Это проблематично, потому что вы не можете напрямую нажать имя класса в вектор. Вы можете либо вставить объект класса в вектор, либо нажать ссылку или указатель на тип класса в вектор. Например:

vectorOfGamers.push_back(Player(name, id)) 
    //^^assuming name and id are parameters to the vector, call Player constructor 
    //^^In other words, push `instance` of Player class into vector 

Вопрос 2:

These 3 classes derives from Gamer. Can I create vector to hold objects of Dealer, Bot and Player at the same time? How do I do that?

Да вы можете. Вы можете создать вектор указателей, который указывает на базовый класс Gamer. Хорошим выбором является использование вектора smart_pointer, поэтому вам не нужно самостоятельно управлять памятью указателей. Поскольку остальные три класса получены из Gamer, на основе полиморфизма вы можете назначить объекты производного класса указателям базового класса. Вы можете найти более подробную информацию из этой публикации: std::vector of objects/pointers/smart pointers to pass objects (buss error: 10)?

1

Вы не можете вставить класса в вектор, вы можете вставить объект (при условии, что он относится к правильному типу или кабриолету).

Если тип Player имеет конструктор по умолчанию, вы можете создать временный объект, делая Player(), и это должно работать для вашего случая:

vectorOfGamers.push_back(Player()); 
0
// create a vector of unknown players. 
std::vector<player> players; 

// resize said vector to only contain 6 players. 
players.resize(6); 

Значения всегда инициализируется, поэтому вектор 6 игроков - это вектор из 6 действительных объектов игрока.

Что касается второй части, вам нужно использовать указатели. Instantiating c++ interface as a child class