Как создать объекты при добавлении их в вектор?
У меня есть вектор С++. Я хочу, чтобы вектор содержал переменное количество объектов.
Visual Studio 2012 дает мне ошибку:
Error: type name is not allowed
Из этого кода на С++:
#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
}
Можно ли создать вектор для одновременного хранения объектов Dealer, Bot и Player? Как мне это сделать? Как я знаю, все объекты в векторе должны быть одного типа.
Ответы
Ответ 1
Чтобы ответить на первую часть вашего вопроса, вы должны создать объект типа Player, прежде чем сможете его использовать. Когда вы говорите push_back(Player)
, это означает "добавить класс Player к вектору", а не "добавить объект типа Player в вектор" (это то, что вы имели в виду).
Вы можете создать объект в стеке следующим образом:
Player player;
vectorOfGamers.push_back(player); // <-- name of variable, not type
Или вы даже можете создать временный объект inline и нажать его (он копируется, когда он помещается в вектор):
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
Ответ 2
Вопрос 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 объектов/указателей/умных указателей для передачи объектов (ошибка шины: 10)?
Ответ 3
Вы не можете вставить класс в вектор, вы можете вставить объект (при условии, что он имеет подходящий тип или конвертируемый) класса.
Если тип Player
имеет конструктор по умолчанию, вы можете создать временный объект, выполнив Player()
, и это должно работать для вашего случая:
vectorOfGamers.push_back(Player());
Ответ 4
// create a vector of unknown players.
std::vector<player> players;
// resize said vector to only contain 6 players.
players.resize(6);
Значения всегда инициализируются, поэтому вектор из 6 игроков представляет собой вектор из 6 действительных объектов игрока.
Что касается второй части, вам нужно использовать указатели.
Создание экземпляра С++-интерфейса в качестве дочернего класса