943,923 Members | Top Members by Rank

Ad:
  • C++ Discussion Thread
  • Marked Solved
  • Views: 636
  • C++ RSS
Jun 12th, 2009
0

Static Objects of class within that class

Expand Post »
I'm wondering if this is even possible in C++. Here's what I did in java a while back:
java Syntax (Toggle Plain Text)
  1. class Suit {
  2. public static Suit Hearts = new Suit("Hearts");
  3. public static Suit Clubs = new Suit("Clubs");
  4. public static Suit Diamonds = new Suit("Diamonds");
  5. public static Suit Spades = new Suit("Spades");
  6. private String value;
  7.  
  8. private Suit(String suit)
  9. {
  10. value = suit;
  11. }
  12.  
  13. public String getValue()
  14. {
  15. return value;
  16. }
  17. }

After trying many ways to do this in C++, I keep getting back to the error that:
only static const integral data members can be initialized within a class.
I know I could accomplish something similar with an enum Suits {Hearts, Spades, Diamonds, Clubs} , but I really would like to have the string associated with it.

Does anybody have any idea how to do this?
Reputation Points: 10
Solved Threads: 5
Junior Poster in Training
chaines51 is offline Offline
54 posts
since Jun 2009
Jun 12th, 2009
1

Re: Static Objects of class within that class

Of course, all possible in C++
That's an improvisation:
C++ Syntax (Toggle Plain Text)
  1. /// suite.h (class Suite definition)
  2. class Suite
  3. {
  4. public:
  5. Suite() {}
  6. Suite(const Suite& suit):value(suit.value) {}
  7. static const Suite
  8. Hearts,
  9. Clubs,
  10. Diamonds,
  11. Spades;
  12. /// that's all, add some methods...
  13. const string& str() const { return value; }
  14. /// add some syntax sugar:
  15. operator bool() const { return !value.empty(); }
  16. bool operator ==(const Suite& suit) {
  17. return value == suit.str();
  18. }
  19. bool operator !=(const Suite& suit) {
  20. return value != suit.str();
  21. }
  22. protected: // there are four colours only
  23. Suite(const char* suit):value(suit) {}
  24. private:
  25. string value;
  26. };
  27. inline // add stream output support
  28. ostream& operator <<(ostream& os, const Suite& suit) {
  29. return os << suit.str();
  30. }
  31. /// suite.cpp (class Suite implementation)
  32. const Suite
  33. Suite::Hearts("Hearts"),
  34. Suite::Clubs ("Clubs"),
  35. Suite::Diamonds("Diamonds"),
  36. Suite::Spades("Spades")
  37. ;
  38. /// test.cpp:
  39. /// more syntax sugar for lazies
  40. const Suite&
  41. Hearts = Suite::Hearts,
  42. Clubs = Suite::Clubs,
  43. Diamonds = Suite::Diamonds,
  44. Spades = Suite::Spades
  45. ;
  46.  
  47. int main()
  48. {
  49. Suite suit;
  50. suit = Spades;
  51. Suite card(Clubs);
  52. if (card && suit == Spades)
  53. cout << suit << '\t' << card << endl;
  54. return 0;
  55. }
Last edited by ArkM; Jun 12th, 2009 at 5:11 am.
Reputation Points: 1234
Solved Threads: 347
Postaholic
ArkM is offline Offline
2,001 posts
since Jul 2008
Jun 12th, 2009
0

Re: Static Objects of class within that class

OK.
c++ Syntax (Toggle Plain Text)
  1. Suite(const Suite& suit):value(suit.value) {}
what exactly does that line MEAN? Specifically the ...:value(suit.value){} part...
Reputation Points: 10
Solved Threads: 5
Junior Poster in Training
chaines51 is offline Offline
54 posts
since Jun 2009
Jun 12th, 2009
0

Re: Static Objects of class within that class

This part is so called ctor-initializer-list. In C++ it's a preferred way to initialize class members and the only method to pass constructor arguments to base class(es) constructors (the last feature is not used here). Alas, it's impossible to initialize non-integral types static data members in ctor-initializer-list. That's why we do it separately in lines 32-37.

So
C++ Syntax (Toggle Plain Text)
  1. Suite(const Suite& suit):value(suit.value) {}
is the class Suite copy constructor: it creates a Suite object from another object of the same type.

The point is that we must define all needed constructors (default constructor - line #5, copy constructor - line #6) if a class has user-defined constructor (see line #23).

Take into account that I don't want to allow users to construct arbitrary Suite objects (like Suite card("Cheat") ). That's why the constructor defined in line #23 is protected. Now we can initialize four static Suite objects (lines 32-37) and construct all others via the copy constructor.

To allow Suite object arrays we need Suite default constructor (a constructor without parameters).

Oh, as usually {} means copy constructor body (a constructor is a member function). It's inline constructor - no need to call any real functions to construct a Suite object with this constructor.

More questions?..
Last edited by ArkM; Jun 12th, 2009 at 1:45 pm.
Reputation Points: 1234
Solved Threads: 347
Postaholic
ArkM is offline Offline
2,001 posts
since Jul 2008
Jun 12th, 2009
0

Re: Static Objects of class within that class

In addition:
Change lines 40-45 in my code above to
C++ Syntax (Toggle Plain Text)
  1. /// more syntax sugar for lazies
  2. const Suite
  3. &Hearts = Suite::Hearts,
  4. &Clubs = Suite::Clubs,
  5. &Diamonds = Suite::Diamonds,
  6. &Spades = Suite::Spades
  7. ;
Probably it's more effective...
I hope you understand that it's an optional code...
Reputation Points: 1234
Solved Threads: 347
Postaholic
ArkM is offline Offline
2,001 posts
since Jul 2008
Jun 12th, 2009
0

Re: Static Objects of class within that class

No sir, I understand the rest of it
But, just to make sure: Those constructors could have been written like this:
c++ Syntax (Toggle Plain Text)
  1. Suite(const Suite & suit)
  2. {
  3. value = suit.value;
  4. }
  5. Suite(const char* suit)
  6. {
  7. value = suit
  8. }
but it's just more efficient the other way, because it doesn't initialize value first? Would it actually initialize value first anyway, since it isn't an object?

Thanks a million.
Reputation Points: 10
Solved Threads: 5
Junior Poster in Training
chaines51 is offline Offline
54 posts
since Jun 2009
Jun 12th, 2009
0

Re: Static Objects of class within that class

Your constructor variant with assignments has the same effect as mine. However as usually assignments in constructors (or even anywhere) are less effective than initialization with ctor-initializers (and are less clear). Yes, formally in your case the compiler initializes an empty string member then creates a temporary string object (for Suite(const char*) constructor) and performs assignment after that. Besides that, ctor-initializer semantically (and pragmatically) directs a (good) compiler to the best optimization of constructor codes.

That's why ctor-initiaslizer-lists are better than assignments. Whenever you have a choice, select ctor-initializer. Don't forget: a constructor is intended for an object initialization.
Reputation Points: 1234
Solved Threads: 347
Postaholic
ArkM is offline Offline
2,001 posts
since Jul 2008

This thread is solved

Either the thread starter or a moderator has marked this thread as solved. You can most likely trust the responses and answers given. There is most likely no reason for any further responses to be posted here. If you have a related question, please start a new thread in this forum instead.

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in C++ Forum Timeline: deleting the repeated numbers
Next Thread in C++ Forum Timeline: Graphical Dos Interface





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC