Skip to main content
gamedev.net
🔒 Locked

Vector Item Initialization

Started by Bincho 4 replies 1.1k views
Original Post
Bincho
Bincho
Hi. Felt like saying that as it's my first post and all. I'm trying to figure out an easy way to automatically initialize all elements in a vector to a certain value. I've looked through a book I have on the standard library, and it looks like the only way to do it without looping through the whole vector and manually assigning a value is with a custom allocator. I'm sort of hoping there's an easier way than doing that, but if there isn't I'll just attempt to add an allocator. In case anyone wants to know the context, I'm trying to get a vector of pointers to initialize to zero. I'd also appreciate an example if anyone has the spare time and the knowledge.
snk_kid
snk_kid
Quote:
Original post by Bincho
I'm trying to get a vector of pointers to initialize to zero.


you can specifiy the size & initialize all elements to some example value at construction e.g.

std::vector<int*> v(30, 0); //30 pointers to int initialized to zero


Don't try and does this with new because you'll end up assigning all the pointers to the same instance, you'll need to write a generator function/functor. e.g

#include <iterator>#include <algorithm>#include <vector>class gen_int {	const int default_value;public:	gen_int(int i = 0): default_value(i) {}	int* operator()() const {		return new int(default_value);	}};int main() {   const std::vector<int*>::size_type N = 30;   std::vector<int*> v;   std::generate_n(std::back_inserter(v), N, gen_int(10));}
Jingo
Jingo
Quote:
Original post by snk_kid
...int main() {   const std::vector<int*>::size_type N = 30;   std::vector<int*> v;   std::generate_n(std::back_inserter(v), N, gen_int(10));}


delete what thy new :)
Bincho
Bincho
Okay, that at least compiled and I'm going to trust that it worked until I get to a point where I can test it. I have enough faith, though. :) Here's what I have so far, in case I'm doing something else wrong. I didn't know of a better way to delete each item in the vector, so I chose to simply make a delete function for each Piece. Anyway, you'll see. It's basically the preliminary stages of a Tic-Tac-Toe game, but I wanted the board class to be reusable in my next project.
// board.hpp#pragma once#include <vector>#include <algorithm>#include ".\piece.hpp"class Board{public:	Board(int width = 3, int height = 3);	~Board();	void Draw();	void PlacePiece();	void MovePiece();private:	int width_;	int height_;	std::vector<Piece*> cells_;};inline Piece* pieceInit();inline void deletePiece(Piece* piece);


And...

// board.cpp#include ".\board.hpp"Board::Board(int width, int height)	: width_(width), height_(height){	std::vector<Piece*>::size_type number_of_spaces = width_ * height_;	cells_.reserve(number_of_spaces);	std::generate_n(std::back_inserter(cells_), number_of_spaces, pieceInit);}Board::~Board(){	for_each(cells_.begin(), cells_.end(), deletePiece);}Piece* pieceInit(){	return 0;}void deletePiece(Piece* piece){	delete piece;}


I hope I applied the idea correctly. Thanks for the help.

Edit: Yeah, I know I'm not doing any error checking and whatnot yet...
snk_kid
snk_kid
if your only initializing all elements to zero then you can use the first method i showed, note also if you wont functions to have a chance of being inlined it should be defined in the same file as it was declared in and the inlined keyword usually goes on the definition of function not on declaration/prototype.

You should also probably define what it means to copy & assign because currently there is a default copy constructor implicitly defined that will copy a vector of pointers to a vector of pointers meaning they will both refer to the same instance (shallow copying) weather that is what you intend or not depends on your requirements, if you don't wont copy/value schematics then define the copy constructor & assignement operator as private but from the way your deleting your pointers in the destructor it looks like you do wont deep copy/value schematics.

one last thing technically std::for_each is a non-mutative function ;-) so i'd use transform instead but its okay to do.

revised version with copy schematics:
board.hpp
#include <vector>struct Piece {};Piece* deletePiece(Piece* piece);Piece* copy_piece(const Piece* const);struct Board {	typedef std::vector<Piece*> vec_of_pieces;	typedef vec_of_pieces::size_type size_type;private:	size_type width_;	size_type height_;	std::vector<Piece*> cells_;	void copy_all(const vec_of_pieces& v);	void clear_all();public:	Board(size_type width = 3, size_type height = 3);	Board(const Board&); //copy-constructor	Board& operator=(const Board&); //assignement operator	~Board();	void Draw();	void PlacePiece();	void MovePiece();	};inline Piece* deletePiece(Piece* piece) {	delete piece; return 0;}inline Piece* copy_piece(const Piece* const p1) {	return new Piece(*p1); //piece must have an appropriate copy constructor defined either implicitly or explicitly}


board.cpp
#include "board.hpp"#include <algorithm>void Board::copy_all(const Board::vec_of_pieces& v) {	cells_.reserve(v.size());	std::transform(v.begin(), v.begin(), std::back_inserter(cells_), copy_piece); }void Board::clear_all() {	std::transform(cells_.begin(), cells_.end(), cells_.begin(), deletePiece);	cells_.clear();}Board::Board(Board::size_type width,	     Board::size_type height): width_(width), height_(height), cells_((width_ * height_), 0) {}Board::Board(const Board& b): width_(b.width_), height_(b.height_), cells_() {	copy_all(b.cells_);}Board& Board::operator=(const Board& b) {	if(this != &b) { //prevent self assignement		width_ = b.width_;		height_ = b.height_;		clear_all();		copy_all(b.cells_);	}	return *this;}Board::~Board() {	clear_all();}


if Piece is a polymorphic type then you'll have to make some slight changes to the above using either virtual constructor idiom or a factory method design pattern

[Edited by - snk_kid on October 29, 2004 8:58:38 AM]
Bincho
Bincho
Awesome. I'll make the necessary changes to my stuff tomorrow :) Thanks for all the help. It's getting way too... early? Maybe tomorrow I'll finish it if I'm lucky. But yeah, Piece is (or will be) a polymorphic type. I also moved the piece specific functions into the Piece class as static functions, because I think they belong there as opposed to floating around in the Board class. Yep. I think that's about it. Thanks again.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.