help using vector in place of an array

J

J. Campbell

I'm comfortable with arrays from previous programming, and understand
the advantages of c++ vectors...I just don't understand how to use
them :~( Can you help me to use a vector<string> in the following
compilable example instead of the string* array?

Thanks,

Joe

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

class Deck {
private:
string* the_deck; //I want to use vector<string> the_deck
string cards;
string suits;
int decksize;
public:
Deck(string cards_in, string suits_in);
~Deck();

void make_new();
void show();
};

void wait();

const string suits = "\x5\x4\x3\x6";
const string cards = "23456789TJQKA";

//-----------------------------
int main(){
Deck Pack(cards, suits);
Pack.make_new();
Pack.show();

wait();
return 0;
}
//------------------------------

void wait(){
cout << "\n<Enter> to continue...";
string z;
getline(cin,z);
}

Deck::Deck(string cards_in, string suits_in){
cards = cards_in;
suits = suits_in;
decksize = suits.size() * cards.size();
the_deck = new string [decksize];
}

Deck::~Deck(){
delete[] the_deck;
}

void Deck::show(){
for(int i = 0; i < (cards.size() * suits.size()); ++i){
if (!(i % cards.size()) && i) cout << '\n';
cout << the_deck << " ";
}
cout << endl;
}

void Deck::make_new(){
cout << "New Deck Created" << endl;
int count = 0;
for(int i = 0; i < suits.size(); ++i)
for(int j = 0; j < cards.size(); ++j){
the_deck[count]=cards[j];
the_deck[count++]+=suits;
}
}
 
R

Ron Natalie

J. Campbell said:
private:
string* the_deck; //I want to use vector<string> the_deck

vector said:
the_deck = new string [decksize];
the_deck.resize(decksize);

delete[] the_deck;

delete this line.

The program works fine (apparently).
 
G

Gianni Mariani

J. Campbell said:
I'm comfortable with arrays from previous programming, and understand
the advantages of c++ vectors...I just don't understand how to use
them :~( Can you help me to use a vector<string> in the following
compilable example instead of the string* array?

Thanks,

Joe

Here's a swag:
#include <iostream>
#include <string>
//#include <vector>
using namespace std;

class Deck {
private:
// string* the_deck; //I want to use vector<string> the_deck

vector said:
string cards;
string suits;
int decksize;
public:
Deck(string cards_in, string suits_in);
~Deck();

void make_new();
void show();
};

void wait();

const string suits = "\x5\x4\x3\x6";
const string cards = "23456789TJQKA";

//-----------------------------
int main(){
Deck Pack(cards, suits);
Pack.make_new();
Pack.show();

wait();
return 0;
}
//------------------------------

void wait(){
cout << "\n<Enter> to continue...";
string z;
getline(cin,z);
}

Deck::Deck(string cards_in, string suits_in)
: cards( cards_in ),
suits( suits_in ),
decksize( suits.size() * cards.size() ),
the_deck( suits.size() * cards.size() )
{

use the member initialization syntax.
// cards = cards_in;
// suits = suits_in;
// decksize = suits.size() * cards.size();
// the_deck = new string [decksize];
}

Deck::~Deck(){

no delete - a vector will destroy elements in the vector
// delete[] the_deck;
}

void Deck::show(){
for(int i = 0; i < (cards.size() * suits.size()); ++i){
if (!(i % cards.size()) && i) cout << '\n';
cout << the_deck << " ";
}
cout << endl;
}

void Deck::make_new(){
cout << "New Deck Created" << endl;
int count = 0;
for(int i = 0; i < suits.size(); ++i)
for(int j = 0; j < cards.size(); ++j){
the_deck[count]=cards[j];
the_deck[count++]+=suits;
}
}
 
M

Marcin Vorbrodt

J. Campbell said:
I'm comfortable with arrays from previous programming, and understand
the advantages of c++ vectors...I just don't understand how to use
them :~( Can you help me to use a vector<string> in the following
compilable example instead of the string* array?

Thanks,

Joe

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

class Deck {
private:
string* the_deck; //I want to use vector<string> the_deck
string cards;
string suits;
int decksize;
public:
Deck(string cards_in, string suits_in);
~Deck();

void make_new();
void show();
};

void wait();

const string suits = "\x5\x4\x3\x6";
const string cards = "23456789TJQKA";

//-----------------------------
int main(){
Deck Pack(cards, suits);
Pack.make_new();
Pack.show();

wait();
return 0;
}
//------------------------------

void wait(){
cout << "\n<Enter> to continue...";
string z;
getline(cin,z);
}

Deck::Deck(string cards_in, string suits_in){
cards = cards_in;
suits = suits_in;
decksize = suits.size() * cards.size();
the_deck = new string [decksize];
}

Deck::~Deck(){
delete[] the_deck;
}

void Deck::show(){
for(int i = 0; i < (cards.size() * suits.size()); ++i){
if (!(i % cards.size()) && i) cout << '\n';
cout << the_deck << " ";
}
cout << endl;
}

void Deck::make_new(){
cout << "New Deck Created" << endl;
int count = 0;
for(int i = 0; i < suits.size(); ++i)
for(int j = 0; j < cards.size(); ++j){
the_deck[count]=cards[j];
the_deck[count++]+=suits;
}
}


Sure this, here it is:



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

class Deck {
private:
string cards;
string suits;
vector<string> the_deck;

public:
Deck(const string& cards_in, const string& suits_in);

void make_new();
void show() const;
};

void wait();

const string suits = "\x5\x4\x3\x6";
const string cards = "23456789TJQKA";

//-----------------------------
int main(){
Deck Pack(cards, suits);
Pack.make_new();
Pack.show();

wait();
return 0;
}
//------------------------------

void wait(){
cout << "\n<Enter> to continue...";
string z;
getline(cin,z);
}

Deck::Deck(const string& cards_in, const string& suits_in)
: cards(cards_in), suits(suits_in), the_deck(cards.size() * suits.size()) {}

void Deck::show() const {
for(unsigned int i = 0; i < the_deck.size(); ++i) {
if(!(i % cards.size()) && i) cout << endl;
cout << the_deck << " ";
}
cout << endl;
}

void Deck::make_new() {
cout << "New Deck Created" << endl;
int count = 0;
for(int i = 0; i < suits.size(); ++i) {
for(int j = 0; j < cards.size(); ++j) {
the_deck[count] = cards[j];
the_deck[count++]+= suits;
}
}
}



Notice empty constructor body due to initialization list. Also gor rid of
one int variable in your class, as well as the constructor. Compiles and
works just fine under mingw GCC 3.2.3

Hope this helps.

Martin
 
M

Michael Winter

on 22 Sept 03:
J. Campbell said:
I'm comfortable with arrays from previous programming, and understand
the advantages of c++ vectors...I just don't understand how to use
them :~( Can you help me to use a vector<string> in the following
compilable example instead of the string* array?

Thanks,

Joe

Here's a swag:
#include <iostream>
#include <string>
//#include <vector>
using namespace std;

class Deck {
private:
// string* the_deck; //I want to use vector<string> the_deck

vector said:
string cards;
string suits;
int decksize;
public:
Deck(string cards_in, string suits_in);
[SNIP]
Deck::Deck(string cards_in, string suits_in)
: cards( cards_in ),
suits( suits_in ),
decksize( suits.size() * cards.size() ),
the_deck( suits.size() * cards.size() )
{

use the member initialization syntax.


According to the C++ Language Reference in the MSDN Library (sorry, I
don't have the actual C++ specification), that initialisation may not
work correctly.

From "Initialising Member Objects":

"The order in which the member initializers are specified in the
constructor does not affect the order in which the members are
constructed; the members are constructed in the order in which they
are declared in the class."

[From MSDN C++ Language Reference > Special Member Functions >
Initialization Using Special Member Functions > Initializing Bases and
Members > Initializing Member Objects]

And, the order in which they were declared in the class was 'the_deck'
first, then the remaining members (in the order you list them). If
the MSDN Library is correct here, 'the_deck' won't initialize
correctly as 'cards' and 'suits' haven't been initialised. So, is it
(MSDN) correct?

Mike
 
G

Gianni Mariani

Michael said:
on 22 Sept 03:
....snippitty

Yikes !

According to the C++ Language Reference in the MSDN Library (sorry, I
don't have the actual C++ specification), that initialisation may not
work correctly.

From "Initialising Member Objects":

"The order in which the member initializers are specified in the
constructor does not affect the order in which the members are
constructed; the members are constructed in the order in which they
are declared in the class."

Yep - you're right.

Very sloppy. Bad bad bad. Grot, even.

I had meant to use the parameters like this ...

decksize( suits_in.size() * cards_in.size() )
the_deck( suits_in.size() * cards_in.size() )
[From MSDN C++ Language Reference > Special Member Functions >
Initialization Using Special Member Functions > Initializing Bases and
Members > Initializing Member Objects]

And, the order in which they were declared in the class was 'the_deck'
first, then the remaining members (in the order you list them). If
the MSDN Library is correct here, 'the_deck' won't initialize
correctly as 'cards' and 'suits' haven't been initialised. So, is it
(MSDN) correct?

MSDN is probably correct.

In general, I try not to rely on the order of construction because I
think it's asking for trouble when someone "rearranges" some of the
class members. It's not to say that you can't use the order of
initialization to your benefit, it's just that you probably need to note
it in the comments of the members very clearly that order is important
and only do that when there is no other alternative.

Good catch.
 
J

J. Campbell

Marcin Vorbrodt said:
Sure this, here it is:

Notice empty constructor body due to initialization list. Also gor rid of
one int variable in your class, as well as the constructor. Compiles and
works just fine under mingw GCC 3.2.3

Hope this helps.

Martin

It helps a ton. Thanks-JC
 
J

J. Campbell

Marcin Vorbrodt said:
Sure this, here it is:



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

class Deck {
private:
string cards;
string suits;
vector<string> the_deck;

public:
Deck(const string& cards_in, const string& suits_in);

void make_new();
void show() const;
};

void wait();

const string suits = "\x5\x4\x3\x6";
const string cards = "23456789TJQKA";

//-----------------------------
int main(){
Deck Pack(cards, suits);
Pack.make_new();
Pack.show();

wait();
return 0;
}
//------------------------------

void wait(){
cout << "\n<Enter> to continue...";
string z;
getline(cin,z);
}

Deck::Deck(const string& cards_in, const string& suits_in)
: cards(cards_in), suits(suits_in), the_deck(cards.size() * suits.size()) {}

Questions about this construct--
What is the significance of the colon?
What is the name of the colon operator when used in this manner?
What is the advantage of, eg, cards(cards_in); assignment before the
body of the constructor compared to cards = cards_in; inside the
constructor?
If you are using the form you showed, why seed the constants in the
constructor definition, rather than in the class declaration?
And finally, I tried initializing some variables with the
variablename(value) format with mixed results. For example, in the
body of a constructor, bits_per_word is an int:
bits_per_word(sizeof(unsigned int) * CHAR_BIT); //doesn't compile
bits_per_word = sizeof(unsigned int) * CHAR_BIT; //compiles fine

Thanks again--JC

void Deck::show() const {
for(unsigned int i = 0; i < the_deck.size(); ++i) {
if(!(i % cards.size()) && i) cout << endl;
cout << the_deck << " ";
}
cout << endl;
}

void Deck::make_new() {
cout << "New Deck Created" << endl;
int count = 0;
for(int i = 0; i < suits.size(); ++i) {
for(int j = 0; j < cards.size(); ++j) {
the_deck[count] = cards[j];
the_deck[count++]+= suits;
}
}
}



Notice empty constructor body due to initialization list. Also gor rid of
one int variable in your class, as well as the constructor. Compiles and
works just fine under mingw GCC 3.2.3

Hope this helps.

Martin
 
G

Gianni Mariani

J. Campbell said:
.... SNIP


Questions about this construct--
What is the significance of the colon?

Syntax. This is valid only on a constructor definition to define an
initializer list.
What is the name of the colon operator when used in this manner?

It's not an operator. It just signifies there is an initializer list.
Call it syntactic sugar. I'm not familiar will all the ambiguities it
might resolve but I'd say that it makes error detection of missing
semicolons a little easier.
What is the advantage of, eg, cards(cards_in); assignment before the
body of the constructor compared to cards = cards_in; inside the
constructor?

Check out this code.

#include <iostream>

struct Element
{
int a_value;

Element( int value = 0 )
: a_value( value )
{
std::cout << "Constructed with value " << a_value << "\n";
}

Element & operator = ( int value )
{
a_value = value;
std::cout << "Assignment with value " << a_value << "\n";
return *this;
}
};

struct B
{
Element v;

B()
: v( 1111 )
{
}
};

struct C
{
Element v;

C()
{
v = 4444;
}
};


int main()
{
std::cout << "Construction of B:\n";
B b;

std::cout << "\nConstruction of C:\n";
C c;
}


Construction of B:
Constructed with value 1111

Construction of C:
Constructed with value 0
Assignment with value 4444

You'll notice that if you use the initializer list ( like we have in B)
there is only construction involved.
If you are using the form you showed, why seed the constants in the
constructor definition, rather than in the class declaration?

What constants ?
And finally, I tried initializing some variables with the
variablename(value) format with mixed results.

The TYPE( <parameters> ) syntax is only valid for calling the constructor.

int c( 2 ); // OK

c( 3 ); // NOT ok

c = int( 3 ); // OK contructs temporary int and assigns

Incidently

int c = 2; // is exactly the same as:
int c(2);

For example, in the
body of a constructor, bits_per_word is an int:
bits_per_word(sizeof(unsigned int) * CHAR_BIT); //doesn't compile

expected - you need assignment here since no object is being constructed
(except for temporary int).
bits_per_word = sizeof(unsigned int) * CHAR_BIT; //compiles fine

plain vanilla expression - should work fine.
 
A

Agent Mulder

<Joe>
I'm comfortable with arrays from previous programming, and understand
the advantages of c++ vectors...I just don't understand how to use
them :~( Can you help me to use a vector<string> in the following
compilable example instead of the string* array?
</>

Cool :)

#include <iostream.h>
#include <string>
#include <vector>
//using namespace std;

class Deck {
private:
// string* the_deck; //I want to use vector<string> the_deck
vector<string>the_deck;
string cards;
string suits;
int decksize;
public:
Deck(string cards_in, string suits_in);
~Deck();

void make_new();
void show();
};

void wait();

const string suits = "\x5\x4\x3\x6";
const string cards = "23456789TJQKA";

//-----------------------------
int main(){
Deck Pack(cards, suits);
Pack.make_new();
Pack.show();

wait();
return 0;
}
//------------------------------

void wait(){
cout << "\n<Enter> to continue...";
string z;
getline(cin,z);
}

Deck::Deck(string cards_in, string suits_in)
:
the_deck(52)
{
cards = cards_in;
suits = suits_in;
decksize = suits.size() * cards.size();
// the_deck = new string [decksize];
}

Deck::~Deck(){
// delete[] the_deck;
}

void Deck::show(){
for(int i = 0; i < (cards.size() * suits.size()); ++i){
if (!(i % cards.size()) && i) cout << '\n';
cout << the_deck << " ";
}
cout << endl;
}

void Deck::make_new(){
cout << "New Deck Created" << endl;
int count = 0;
for(int i = 0; i < suits.size(); ++i)
for(int j = 0; j < cards.size(); ++j){
the_deck[count]=cards[j];
the_deck[count++]+=suits;
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top