how to use parametrized constructor with new

Hello. I am trying to figure out how to pass parameters to a constructor using new. Right now I am allocating for an object and then assigning values to the string parameters. I'd like to pass the values and have them created in the second constructor.

So the object created with new is of card_class
1
2
3
4
5
6
7
8
9
10
class card_class {

  public:
    string answer;
    string question;
    int score;

    card_class(void);
    card_class(const string quest, const string ans);
};

and the second constructor is as:
1
2
3
4
card_class::card_class (const string quest, const string ans) {
  question = quest;
  answer = ans;
}

and the calling code is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void deck_class::add_new_card(void) {

  int size;
  card_class *card;

  card = new(card_class);

  // cout << "in add_new_card " << cards.size() << "\n"; 

  card->question = card_pile[cards.size() * 2];
  card->answer = card_pile[cards.size() * 2 + 1];

  // cout << "in add_new_card at end" << cards.size() << "\n";

  cards.push_back(*card);
}


I'd like to alter this so that the line card = new(card_class) can pass the parameters to assign to the values in card_class instead of having to assign them later in the function. How can I do this?

thanks
This will be a pleasant surprise for you: you already have the necessary things in place to do that. Just:
1
2
3
4
5
6
  cards.push_back(
    new card_class(
          card_pile[ cards.size() *2    ],
          card_pile[ cards.size() *2 +1 ]
          )
    );


BTW, if you are just initializing your cards from a static array with a loop somewhere, you can 'cheat' with a little functor:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// Includes you'll need
#include <algorithm>

class deck_class: ...
  {
    ...
  public:
    ...

    // A little functor to take two strings at a time and add them to a deck
    struct take_two
      {
      card_class& cards;
      string      question;
      take_two( card_class& cards ): cards( cards ) { }
      void operator () ( const string& s )
        {
        if (question.empty()) question = s;
        else
          {
          cards.push_back( new card_class( question, s ) );
          question.clear();
          }
        }
      };
  };

const char* const card_pile[] = {
  "How does it work?",
  "Like a charm.",
  "How do you mean?",
  "It's magic."
  };

// Fill my deck_class, 'deck', with the questions and answers interleaved in the static 'card_pile'.
for_each(
  card_pile,
  card_pile +(sizeof( card_pile ) /sizeof( card_pile[ 0 ] )),
  deck_class::take_two( deck.cards )
  );


Hope this helps.
Aye, right now I am reading from a static array hard coded into the program, but I am in the process of changing this to be able to read from files so that the program can be used with different lists.

Thanks for the suggestion about the 2 strings at a time functor. I'm not quite following how the take_two is working though, specifically:
take_two( card_class &cards): cards( cards ) {}
Heh, you can read them from file the same way:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Here's a little helper class to overload >> to read an entire line at a time
// (that is, without clobbering the normal string >> function).
class line_t: public std::string { };
istream& operator >> ( istream&ins, line_t& line )
  {
  string result;
  getline( ins, result );
  return result;
  }

// For every two lines in the file, add a card as (question, answer)
for_each(
  istream_iterator <line_t> ( cin ),
  istream_iterator <line_t> (),
  deck_class::take_two( deck.cards )
  );


The way that take_two works is a pretty simple trick. You will see it right away.

Every time the for_each() feeds it a new string (via the () operator function), it checks to see if it already has the last string given to it. If not, it just remembers the string and returns. But if it already remembered a string, now it has two strings that it can use to make a new Q&A card.

Adding a new card is a little tricky though: there is the need to allocate one on the heap and then stick the address in the deck of cards (a list of pointers to a card). So to keep it simple the take_two object also keeps a reference to the card_class container that it can use to add the card.

Hope this helps. :-)
Topic archived. No new replies allowed.