|
|
 |
 |
 |
 |
asking for an opinion from the collective wisdom here
I was simply wondering if this was a mal-formed class header: #ifndef _items_h_ #define _items_h_ #include <iostream> #include <string> #include <vector> using namespace std; class Item { public: Item( float weight = 0, bool set_can_equip = false, bool set_can_attack = false, bool set_can_defend = false, bool set_can_drink = false, bool set_can_eat = false, bool set_can_use = false, bool set_is_consumable = false, bool set_is_magical = false ); //Below are the set and get functions for all variables in this class void set_weight( float weight ) { item_weight = weight; } float get_weight() { return item_weight; } void set_can_equip( bool set_can_equip ) { can_equip = set_can_equip; } bool get_can_equip() { return can_equip; } void set_can_attack( bool set_can_attack ) { can_attack = set_can_attack; } bool get_can_attack() { return can_attack; } void set_can_defend( bool set_can_defend ) { can_defend = set_can_defend; } bool get_can_defend() { return can_defend; } void set_can_drink( bool set_can_drink ) { can_drink = set_can_drink; } bool get_can_drink() { return can_drink; } void set_can_eat( bool set_can_eat ) { can_eat = set_can_eat; } bool get_can_eat() { return can_eat; } void set_can_use( bool set_can_use ) { can_use = set_can_use; } bool get_can_use() { return can_use; } void set_is_consumable( bool set_is_consumable ) { is_consumable = set_is_consumable; } bool get_is_consumable() { return is_consumable; } void set_is_magical( bool set_is_magical ) { is_magical = set_is_magical; } bool get_is_magical() { return is_magical; } void describe(); // simply returns description (see below) void clear_describe(); // clears description void add_describe( string line_to_add ); /*Line above checks to see if description is set to either need_set or desc_cleared, and if so description.clear() then push_back( line_to_add ), else just push_back( line_to_add)*/ private: // These are stats that will be set for every item created string need_set; // description is initialized with this string desc_cleared; // description will be set to this after it has been cleared vector<string> description; // This is to allow multi-line descriptions float item_weight; // These are pretty self explanatory I think bool can_equip; bool can_attack; bool can_defend; bool can_drink; bool can_eat; bool can_use; bool is_consumable; bool is_magical; };
#endif but as I read along I was confused over something. The above works just fine, but I was also wondering should the constructor be this: Item( float weight = 0, bool set_can_equip = false, bool set_can_attack = false, bool set_can_defend = false, bool set_can_drink = false, bool set_can_eat = false, bool set_can_use = false, bool set_is_consumable = false, bool set_is_magical = false ); with a constructor body like this in the cpp file: Item::Item( float weight, bool set_can_equip, bool set_can_attack, bool set_can_defend, bool set_can_drink, bool set_can_eat, bool set_can_use ) { item_weight = weight; can_equip = set_can_equip; can_attack = set_can_attack; can_defend = set_can_defend; can_drink = set_can_drink; can_eat = set_can_eat; can_use = set_can_use; is_consumable = set_is_consumable; is_magical = set_is_magical; need_set = "You need to set a description here!\n"; desc_cleared = "The description has been cleared.\n"; description.clear(); description.push_back( need_set ); }
or this: Item() : float weight( 0 ), bool can_equip( false ), bool can_attack( false ), bool can_defend( false ), bool can_drink( false ), bool can_eat( false ), bool can_use( false ), bool is_consumable( false ), bool is_magical( false ); and lose the entire body of the constructor in the cpp file? I will need to pass in parameters to override the defaults when I instantiate the objects. Question 1: Is this a mal-formed class header? Question 2: Which should I use for the initialization list? Thanks in advance. DN -- [there are no x's in my email] I have the right to remain silent (and should probably use it as much as possible) Anything I type can and will be used against me in a court of idiocy I have the right to be wrong (and probably am) If I can not furnish my own wrongness I'm sure someone will provide it for me.
Devon Null wrote: > I was simply wondering if this was a mal-formed class header: > #ifndef _items_h_ > #define _items_h_
Yes, you are malformed right here. Per the Standard, any identifier with a leading underscore is reserved to the implementation in the global namespace. _items_h_ is in the global namespace.
Devon Null <theronnights @xgmailx.com> wrote: > I was wondering should the constructor be this: > Item( float weight = 0, bool set_can_equip = false, bool set_can_attack > = false, bool set_can_defend = false, bool set_can_drink = false, bool > set_can_eat = false, bool set_can_use = false, bool set_is_consumable = > false, bool set_is_magical = false ); > with a constructor body like this in the cpp file: > Item::Item( float weight, bool set_can_equip, bool set_can_attack, bool > set_can_defend, bool set_can_drink, bool set_can_eat, bool set_can_use ) > { > item_weight = weight; > can_equip = set_can_equip; > can_attack = set_can_attack; > can_defend = set_can_defend; > can_drink = set_can_drink; > can_eat = set_can_eat; > can_use = set_can_use; > is_consumable = set_is_consumable; > is_magical = set_is_magical; > need_set = "You need to set a description here!\n"; > desc_cleared = "The description has been cleared.\n"; > description.clear(); > description.push_back( need_set ); > } > or this: > Item() : float weight( 0 ), bool can_equip( false ), bool can_attack( > false ), bool can_defend( false ), bool can_drink( false ), bool > can_eat( false ), bool can_use( false ), bool is_consumable( false ), > bool is_magical( false ); > and lose the entire body of the constructor in the cpp file? I will need > to pass in parameters to override the defaults when I instantiate the > objects.
You can't lose the entire body of the constructor. However to answer the underlying question, you should use the no argument constructor and just initialize all the variables. Item::Item() : weight( 0 ), can_equip( false ), can_attack( false ), can_defend( false ), can_drink( false ), can_eat( false ), can_use( false ), is_consumable( false ), is_magical( false ) { } At some point you will realize that your code is full of blocks that check the various flags in this class and behave differently depending on the setting of the flag. Then when you learn about polymorphism, you will start writing better classes.
On Jun 3, 1:06 am, "Daniel T." <danie@earthlink.net> wrote:
> Devon Null <theronnights @xgmailx.com> wrote: > > I was wondering should the constructor be this: > > Item( float weight = 0, bool set_can_equip = false, bool set_can_attack > > = false, bool set_can_defend = false, bool set_can_drink = false, bool > > set_can_eat = false, bool set_can_use = false, bool set_is_consumable = > > false, bool set_is_magical = false ); > > with a constructor body like this in the cpp file: > > Item::Item( float weight, bool set_can_equip, bool set_can_attack, bool > > set_can_defend, bool set_can_drink, bool set_can_eat, bool set_can_use ) > > { > > item_weight = weight; > > can_equip = set_can_equip; > > can_attack = set_can_attack; > > can_defend = set_can_defend; > > can_drink = set_can_drink; > > can_eat = set_can_eat; > > can_use = set_can_use; > > is_consumable = set_is_consumable; > > is_magical = set_is_magical; > > need_set = "You need to set a description here!\n"; > > desc_cleared = "The description has been cleared.\n"; > > description.clear(); > > description.push_back( need_set ); > > } > > or this: > > Item() : float weight( 0 ), bool can_equip( false ), bool can_attack( > > false ), bool can_defend( false ), bool can_drink( false ), bool > > can_eat( false ), bool can_use( false ), bool is_consumable( false ), > > bool is_magical( false ); > > and lose the entire body of the constructor in the cpp file? I will need > > to pass in parameters to override the defaults when I instantiate the > > objects. > You can't lose the entire body of the constructor. However to answer the > underlying question, you should use the no argument constructor and just > initialize all the variables. > Item::Item() : > weight( 0 ), > can_equip( false ), > can_attack( false ), > can_defend( false ), > can_drink( false ), > can_eat( false ), > can_use( false ), > is_consumable( false ), > is_magical( false ) > { } > At some point you will realize that your code is full of blocks that > check the various flags in this class and behave differently depending > on the setting of the flag. Then when you learn about polymorphism, you > will start writing better classes.- Hide quoted text - >
both forms can be used for ctors but the later is better when const data members exist and the former is needed when members have to be assigned assciated values: int f(int,int);//A big function class A{ public: const int m; int n,p; A(int i,int j): p(0), m(f(i,j))//const must be initialized here. {n=m;};/*if n is initailized in the initializer list f is called twice which time expensive.*/
};
On Jun 2, 11:51 pm, red floyd <no.s@here.dude> wrote: > Devon Null wrote: > > I was simply wondering if this was a mal-formed class header: > > #ifndef _items_h_ > > #define _items_h_ > Yes, you are malformed right here. Per the Standard, any identifier > with a leading underscore is reserved to the implementation in the > global namespace. _items_h_ is in the global namespace.
what is wrong with it? This is an avanced technique used in proffesional libraries to prevent probable linker errors generated by repetition.It also decreases compile time. regards, FM
In article <1180823946.495673.55@h2g2000hsg.googlegroups.com>, farid.mehr@gmail.com says... > On Jun 2, 11:51 pm, red floyd <no.s @here.dude> wrote: > > Devon Null wrote: > > > I was simply wondering if this was a mal-formed class header: > > > #ifndef _items_h_ > > > #define _items_h_ > > Yes, you are malformed right here. Per the Standard, any identifier > > with a leading underscore is reserved to the implementation in the > > global namespace. _items_h_ is in the global namespace. > what is wrong with it? > This is an avanced technique used in proffesional libraries to prevent > probable linker errors generated by repetition.It also decreases > compile time.
As he already pointed out, what's wrong is the _name_ you've used. The technique is perfectly legitimate and allowable, but the name you've used is not. If you change to something like: #ifndef ITEMS_H_INCLUDED #define ITEMS_H_INLCUDED you'll be fine, because this name does NOT have a leading underscore like the one you used. -- Later, Jerry. The universe is a figment of its own imagination.
terminator wrote: > On Jun 2, 11:51 pm, red floyd <no.s @here.dude> wrote: >> Devon Null wrote: >>> I was simply wondering if this was a mal-formed class header: >>> #ifndef _items_h_ >>> #define _items_h_ >> Yes, you are malformed right here. Per the Standard, any identifier >> with a leading underscore is reserved to the implementation in the >> global namespace. _items_h_ is in the global namespace. > what is wrong with it?
_items_h_ starts with an underscore. > This is an avanced technique used in proffesional libraries to prevent > probable linker errors generated by repetition.It also decreases > compile time.
Yes, but there are two rules: 1. Never use a name starting with an underscore in the global namespace. 2. Never use a name starting with an underscore followed by a capital letter, or a name containing __ in _any_ namespace. Include guards are very handy, but name them properly. -- rbh
terminator <farid.mehr @gmail.com> wrote: > both forms can be used for ctors but the later is better when const > data members exist and the former is needed when members have to be > assigned assciated values: > int f(int,int);//A big function > class A{ > public: > const int m; > int n,p; > A(int i,int j): > p(0), > m(f(i,j))//const must be initialized here. > {n=m;};/*if n is initailized in the initializer list f is called > twice which time expensive.*/ > };
I try to avoid such micro-optimizations unless profiling has shown that they are necessary. For this specific case, if the function has no side effects, I expect the compiler would be smart enough to cache the return value for the second use.
terminator wrote: > On Jun 2, 11:51 pm, red floyd <no.s @here.dude> wrote: >> Devon Null wrote: >>> I was simply wondering if this was a mal-formed class header: >>> #ifndef _items_h_ >>> #define _items_h_ >> Yes, you are malformed right here. Per the Standard, any identifier >> with a leading underscore is reserved to the implementation in the >> global namespace. _items_h_ is in the global namespace. > what is wrong with it? > This is an avanced technique used in proffesional libraries to prevent > probable linker errors generated by repetition.It also decreases > compile time.
It's not at all advanced. Every header should have include guards. The problem it solves is repeating definitions at compile time, which produces compile-time errors, not linker errors. The problem with this particular example, as has been pointed out in several other messages, is the name of the guard. -- -- Pete Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The Standard C++ Library Extensions: a Tutorial and Reference." (www.petebecker.com/tr1book)
On Jun 3, 8:46 am, "Daniel T." <danie@earthlink.net> wrote:
> terminator <farid.mehr @gmail.com> wrote: > > both forms can be used for ctors but the later is better when const > > data members exist and the former is needed when members have to be > > assigned assciated values: > > int f(int,int);//A big function > > class A{ > > public: > > const int m; > > int n,p; > > A(int i,int j): > > p(0), > > m(f(i,j))//const must be initialized here. > > {n=m;};/*if n is initailized in the initializer list f is called > > twice which time expensive.*/ > > }; > I try to avoid such micro-optimizations unless profiling has shown that > they are necessary. For this specific case, if the function has no side > effects, I expect the compiler would be smart enough to cache the return > value for the second use.- Hide quoted text - >
you pointed to the side effects ;that is exactly what I mean ,and since there is no way for the compiler to guess the existance of such side effects it must not censor your code-or cache the value as you wrote. regards
On Jun 3, 3:23 am, Robert Bauck Hamar <hamro@yahoo.no> wrote:
> terminator wrote: > > On Jun 2, 11:51 pm, red floyd <no.s @here.dude> wrote: > >> Devon Null wrote: > >>> I was simply wondering if this was a mal-formed class header: > >>> #ifndef _items_h_ > >>> #define _items_h_ > >> Yes, you are malformed right here. Per the Standard, any identifier > >> with a leading underscore is reserved to the implementation in the > >> global namespace. _items_h_ is in the global namespace. > > what is wrong with it? > _items_h_ starts with an underscore. > > This is an avanced technique used in proffesional libraries to prevent > > probable linker errors generated by repetition.It also decreases > > compile time. > Yes, but there are two rules: > 1. Never use a name starting with an underscore in the global namespace. > 2. Never use a name starting with an underscore followed by a capital > letter, or a name containing __ in _any_ namespace. > Include guards are very handy, but name them properly. > -- > rbh
header guards from mainstream libraries that I have faced , all have underscored guards. In fact since gaurds are not intended to be used more than a few times - in header related stuff only - , they are the best candidates for dirty names .This way good names can be reserved for more important things which are supposed to be introduced in global namespace. regards
On Jun 7, 2:53 pm, terminator <farid.mehr@gmail.com> wrote:
> On Jun 3, 3:23 am, Robert Bauck Hamar <hamro @yahoo.no> wrote: > > terminator wrote: > > > On Jun 2, 11:51 pm, red floyd <no.s @here.dude> wrote: > > >> Devon Null wrote: > > >>> I was simply wondering if this was a mal-formed class header: > > >>> #ifndef _items_h_ > > >>> #define _items_h_ > > >> Yes, you are malformed right here. Per the Standard, any identifier > > >> with a leading underscore is reserved to the implementation in the > > >> global namespace. _items_h_ is in the global namespace. > > > what is wrong with it? > > _items_h_ starts with an underscore. > > > This is an avanced technique used in proffesional libraries to prevent > > > probable linker errors generated by repetition.It also decreases > > > compile time. > > Yes, but there are two rules: > > 1. Never use a name starting with an underscore in the global namespace. > > 2. Never use a name starting with an underscore followed by a capital > > letter, or a name containing __ in _any_ namespace. > > Include guards are very handy, but name them properly. > header guards from mainstream libraries that I have faced , all have > underscored guards. In fact since gaurds are not intended to be used > more than a few times - in header related stuff only - , they are the > best candidates for dirty names .This way good names can be reserved > for more important things which are supposed to be introduced in > global namespace. Unless the library is part of the implementation, such names are illegal, and result in undefined behavior. Many basic libraries (e.g. Posix) do consider themselves "part of the implementation". Third party libraries which don't, however, are in error if they use such names. Or maybe the fact that they use such names is a signal that they do consider themselves as an extention of the implementation. (At any rate, I tend to consider things like the data base library as "part of the implementation.") -- James Kanze (GABI Software) email:james.ka@gmail.com Conseils en informatique oriente objet/ Beratung in objektorientierter Datenverarbeitung 9 place Smard, 78210 St.-Cyr-l'cole, France, +33 (0)1 30 23 00 34
On 7 Jun, 13:53, terminator <farid.mehr@gmail.com> wrote: > On Jun 3, 3:23 am, Robert Bauck Hamar <hamro @yahoo.no> wrote: > > Yes, but there are two rules: > > 1. Never use a name starting with an underscore in the global namespace. > > 2. Never use a name starting with an underscore followed by a capital > > letter, or a name containing __ in _any_ namespace. > > Include guards are very handy, but name them properly. > header guards from mainstream libraries that I have faced , all have > underscored guards. In fact since gaurds are not intended to be used > more than a few times - in header related stuff only - , they are the > best candidates for dirty names .This way good names can be reserved > for more important things which are supposed to be introduced in > global namespace.
The point is not whether the names are sufficiently dirty to avoid name collisions. The point is that, unless these libraries are part of the implementation, they are invading the "namespace" set aside by the standard for the sole use of the implementation, and that is illegal. Since include guards are #define'd macro names, the best way to avoid name clashes between them and the rest of your code is whatever you normally do to prevent macro names clashing with code. The most common example I've seen is that macro names (including include guards) are always ALL_CAPS and everything else is never ALL_CAPS, but any naming convention that creates a separate "namespace" for macros is sufficient (as long as it doesn't invade the implementation's namespace). And, of course, you can have naming conventions within that to protect include guard names from other macros if you want. For example, include guards always ending in _H and other macros never ending in _H. But again, any naming convention works as long as it doesn't break the two rules above. Gavin Deane
On Jun 8, 11:12 am, James Kanze <james.ka@gmail.com> wrote:
> On Jun 7, 2:53 pm, terminator <farid.mehr @gmail.com> wrote: > > On Jun 3, 3:23 am, Robert Bauck Hamar <hamro@yahoo.no> wrote: > > > terminator wrote: > > > > On Jun 2, 11:51 pm, red floyd <no.s@here.dude> wrote: > > > >> Devon Null wrote: > > > >>> I was simply wondering if this was a mal-formed class header: > > > >>> #ifndef _items_h_ > > > >>> #define _items_h_ > > > >> Yes, you are malformed right here. Per the Standard, any identifier > > > >> with a leading underscore is reserved to the implementation in the > > > >> global namespace. _items_h_ is in the global namespace. > > > > what is wrong with it? > > > _items_h_ starts with an underscore. > > > > This is an avanced technique used in proffesional libraries to prevent > > > > probable linker errors generated by repetition.It also decreases > > > > compile time. > > > Yes, but there are two rules: > > > 1. Never use a name starting with an underscore in the global namespace. > > > 2. Never use a name starting with an underscore followed by a capital > > > letter, or a name containing __ in _any_ namespace. > > > Include guards are very handy, but name them properly. > > header guards from mainstream libraries that I have faced , all have > > underscored guards. In fact since gaurds are not intended to be used > > more than a few times - in header related stuff only - , they are the > > best candidates for dirty names .This way good names can be reserved > > for more important things which are supposed to be introduced in > > global namespace. > Unless the library is part of the implementation, such names are > illegal, and result in undefined behavior. > Many basic libraries (e.g. Posix) do consider themselves "part > of the implementation". Third party libraries which don't, > however, are in error if they use such names. Or maybe the > fact that they use such names is a signal that they do consider > themselves as an extention of the implementation. (At any rate, > I tend to consider things like the data base library as "part of > the implementation.") > -- > James Kanze (GABI Software) email:james.ka@gmail.com > Conseils en informatique oriente objet/ > Beratung in objektorientierter Datenverarbeitung > 9 place Smard, 78210 St.-Cyr-l'cole, France, +33 (0)1 30 23 00 34- Hide quoted text - >
please inform me of the disadvantages of having such form of guards.These are possible combinations of legal characters ,why not to device them?? are they reserved for none-portable issues only? regards, FM
On 9 Jun, 20:59, terminator <farid.mehr@gmail.com> wrote: > On Jun 8, 11:12 am, James Kanze <james.ka @gmail.com> wrote: > > > On Jun 3, 3:23 am, Robert Bauck Hamar <hamro @yahoo.no> wrote: > > > > Yes, but there are two rules: > > > > 1. Never use a name starting with an underscore in the global namespace. > > > > 2. Never use a name starting with an underscore followed by a capital > > > > letter, or a name containing __ in _any_ namespace. > > > > Include guards are very handy, but name them properly. <snip> > > Unless the library is part of the implementation, such names are > > illegal, and result in undefined behavior.
<snip> > please inform me of the disadvantages of having such form of > guards.These are possible combinations of legal characters ,why not to > device them?? are they reserved for none-portable issues only?
Please trim your posts to only include sufficient context to make the post comprehensible. And please don't quote signatures, or the "quoted text" garbage that Google inserts. Thanks. Your answer is in the discussion above. Using names reserved to the implementation results in undefined behaviour. That's it. That's all the disadvantage you need. That statement alone should be sufficient reason for you to avoid such names. comp.lang.c++ discusses *what* is in the C++ standard. As far as *what* goes, that's all there is to it. However, you are asking *why* - and there is generally a reason for these things. One could speculate in this case that the rules above give implementors a separate "namespace" they can use. If they only use the names that are reserved to them, and you never use the names that are reserved to them, you can be confident that you won't suffer name clashes with the implementation. If one didn't want to speculate, comp.std.c++ is a more topical place to discuss *why* the C++ standard is the way it is. Gavin Deane
On Jun 9, 9:59 pm, terminator <farid.mehr@gmail.com> wrote:
> On Jun 8, 11:12 am, James Kanze <james.ka @gmail.com> wrote: > > On Jun 7, 2:53 pm, terminator <farid.mehr @gmail.com> wrote: > > > On Jun 3, 3:23 am, Robert Bauck Hamar <hamro @yahoo.no> wrote: > > > > terminator wrote: > > > > > On Jun 2, 11:51 pm, red floyd <no.s @here.dude> wrote: > > > > >> Devon Null wrote: > > > > >>> I was simply wondering if this was a mal-formed class header: > > > > >>> #ifndef _items_h_ > > > > >>> #define _items_h_ > > > > >> Yes, you are malformed right here. Per the Standard, any identifier > > > > >> with a leading underscore is reserved to the implementation in the > > > > >> global namespace. _items_h_ is in the global namespace. > > > > > what is wrong with it? > > > > _items_h_ starts with an underscore. > > > > > This is an avanced technique used in proffesional libraries to prevent > > > > > probable linker errors generated by repetition.It also decreases > > > > > compile time. > > > > Yes, but there are two rules: > > > > 1. Never use a name starting with an underscore in the global namespace. > > > > 2. Never use a name starting with an underscore followed by a capital > > > > letter, or a name containing __ in _any_ namespace. > > > > Include guards are very handy, but name them properly. > > > header guards from mainstream libraries that I have faced , all have > > > underscored guards. In fact since gaurds are not intended to be used > > > more than a few times - in header related stuff only - , they are the > > > best candidates for dirty names .This way good names can be reserved > > > for more important things which are supposed to be introduced in > > > global namespace. > > Unless the library is part of the implementation, such names are > > illegal, and result in undefined behavior. > > Many basic libraries (e.g. Posix) do consider themselves "part > > of the implementation". Third party libraries which don't, > > however, are in error if they use such names. Or maybe the > > fact that they use such names is a signal that they do consider > > themselves as an extention of the implementation. (At any rate, > > I tend to consider things like the data base library as "part of > > the implementation.") > please inform me of the disadvantages of having such form of > guards. The disadvantage is that they are illegal, and using them causes your code to have undefined behavior. > These are possible combinations of legal characters ,why not to > device them?? are they reserved for none-portable issues only?
The reason the standard bans them is precisely to give the implememters a set of names they can use, without risk of conflicts with your code. Thus, for example, some library header might contain something like: class SomeStandardClass { private: int _items_h_ } ; Now what happens if you include that library header in your header? -- James Kanze (Gabi Software) email: james.ka@gmail.com Conseils en informatique oriente objet/ Beratung in objektorientierter Datenverarbeitung 9 place Smard, 78210 St.-Cyr-l'cole, France, +33 (0)1 30 23 00 34
|
 |
 |
 |
 |
|