Quote:Original post by c4c0d3m0n
1. Yes, an obvious mistake, thank you for pointing it out :) I guess this is a real killer error in a big project, since the compiler didn't tell me about it.
The compiler gives you more than enough rope to hang yourself.
That is one of the reasons why you want to add asserts, unit tests, and write your code so that you aren't directly manipulating pointers and arrays.
Pointer arithmetic is dangerous. There are techniques and practices that let you avoid writing dangerous code, and increase the ability for the compiler to detect bugs before they crash you at runtime.
Quote:Quote:# Use operator=, and remove the setCard function.
6. How would I go on about that? I had trouble using a constructor with Card in combination with the Card array in Deck
The default operator= will work if all of the parts of the card have the same assignment-semantics: once you change std::stringstream to std::string, this will be true.
Quote:Quote:# Use an enumeration instead of chaacters for the card symbol.
7. I thought of that after making this class aswell, but I haven't gotten to changing it yet. I was going to use some #DEFINE 's.
#define is an example of something you should avoid unless you don't have another choice.
enum suit { hearts, diamonds, spades, clubs };
gives you names that the compiler can understand that can be used as constants.
Quote:Quote:# Make the temporary array local to the function where it's used, and pass it by reference to subroutines. Same for shuffle_used.
8. Okay, I don't understadn what you mean with "by reference" though.
struct example { int foo; int bar[100];};void change_example( example& ex ) { ex.foo = 2; ex.bar[0] = -1;}
I passed the struct "example" by reference into the function change_example.
A reference is somewhat like a const pointer to non-const data, with the following exceptions:
foo& a; // error, references *must* be initializedfoo c;foo& b = c; // valid. This is analagous to foo*const x = &cfoo d;b = d; // this is analagous to *x = d
References must be bound. Once bound, references cannot be rebound. Assignment changes the data you are bound to, and not which item you are bound to (this is
very different than pointers).
You can use reference parameters to functions to make functions that change their parameters.
Quote:Quote:# Drop all the get and is functions in the deck class. Overload operator[] instead.
9. This is hocuspocus to me, please explain.
struct example1 { int one, two, three; int& operator[](int index) { if (index == 1) return one; if (index == 2) return two; if (index == 3) return three; assert(false); } int const& operator[](int index)const { if (index == 1) return one; if (index == 2) return two; if (index == 3) return three; assert(false); }};struct datum { int x,y;};struct example2 { datum data[100]; datum& operator[](int index) { assert( index < 100 && index >= 0 ); return data[index]; } datum const& operator[](int index)const { assert( index < 100 && index >= 0 ); return data[index]; }};// use:example2 foo;datum bar = {2,3};foo[5] = bar; // sets foo.data[5] for me
Quote:Quote:# Don't use "safety" values in your switch statements. Write one case per correct value, and assert(false) in the default clause.
10. Same as 9
A better switch statement pattern:
switch( card_value ) { // Name the card (2) case 1: { card_name << 'A'; } break; case 11: { card_name << 'J'; } break; case 12: { card_name << 'Q'; } break; case 13: { card_name << 'K'; } break; default: { assert(false); // we should never see this -- complain card_name << 'A'; // program defensively } break; }