11 Feb, 2010, JohnnyStarr wrote in the 1st comment:
Votes: 0
I'm curious why C++ requires the programmer to define everything that is const.
I understand char pointers, and a few other things, but instance methods? My true question is how Java / C# has managed
to keep so much of the C++ syntax, yet it seems that this isn't as much (if at all) of an issue. I am not questioning the logic
of protecting the application from bugs, I'm just wondering if it is more of a compiler matter.

Also, I'll throw this in here too. having to write:
std::list<std::string&>::iterator str;

// I guess you could do this
using namespace std;

list<string&>::iterator str;
// but it's still a lot

Is so much just to get an iterator object. Is this the only way to do this? I suppose typedef could take care of most of the labor.
I'm afraid I just don't quite get all of C++'s quirks. Maybe that's why I'm all about learning it though!
11 Feb, 2010, Runter wrote in the 2nd comment:
Votes: 0
Eh, "so much" is objective here. An iterator is a completely different typed object (albeit template in your example) from the haystack in C++. It's not a language construct. It just so happens that someone thought the semantics you think is too much effort were appropriate. I agree with them.

Also, I'm not sure why you think const isn't implicit enough. How about an example of where you don't like having to specify const?
11 Feb, 2010, JohnnyStarr wrote in the 3rd comment:
Votes: 0
const char*const instanceMethod(const char*const&) const;


This is contrived to make a point, but it could come up if needed.
I guess I'm spoiled with Ruby.
11 Feb, 2010, David Haley wrote in the 4th comment:
Votes: 0
But in that case, each const actually means something. Presumably they were added for a reason.

Instance methods being const are also quite important. Consider:

const MyObject* a;
a->changeYourself()


where we assume that "changeYourself" is a method that is non-const.

Since a is const, isn't it a violation to try to do something to it that changes it? The whole point of constness is to avoid that. Therefore instance methods that are "const safe" (i.e., don't modify the object) mark themselves as such so that the compiler knows that (a) it's safe to call them on const objects, and (b) it should prevent any modification from occurring from within the method definition.

To be honest I actually really miss constness from time to time in other languages. It's a very nice way of expressing the intention of what you're trying to do. E.g., this method is "read only", or this value is a constant, etc.

And yes, constness is entirely a compiler matter. (Well, I include the symbol resolution process in linkers as part of "the compiler".)


Regarding type verbosity, the next C++ standard will have the "auto" construct that makes a lot of this "type noise" go away. See for example the Wikipedia article on C++0x.

So you could do:

std::list<std::string> myList;
auto listItr = myList.begin();


Of course, C++ will probably always be a more syntax-heavy language than others.
11 Feb, 2010, Tyche wrote in the 5th comment:
Votes: 0
I tend to "type" the minimum necessary "typing" in order to get the compiler to just STFU.
C++ is what it is.
11 Feb, 2010, elanthis wrote in the 6th comment:
Votes: 0
JohnnyStarr said:
I'm curious why C++ requires the programmer to define everything that is const.


Because otherwise the compiler doesn't know what is const. Java is the same.

Quote
I understand char pointers, and a few other things, but instance methods?


What? Are you asking about virtual functions?

Quote
My true question is how Java / C# has managed
to keep so much of the C++ syntax, yet it seems that this isn't as much (if at all) of an issue.


Java and C# are managed/interpreted languages, while C++ is designed to run bare to the metal. C++ is made to be useful as a systems programming language, and no feature in C++ forces additional runtime overhead or complexity that is unnecessary (except exceptions, which are often turned off completely in many C++ domains, including kernels and games).

C++ requires you to be more explicit because you're essentially just using C with a small bit of syntactic sugar on sugar. You can translate C++ into C relatively easily (assuming you have a full C++ parser already written, which is not at all easy to get). Anything you can write in C++ you can write in C without too much extra effort, it'll just be even more verbose and even uglier and even harder to read and you'll have to do a lot of casting and cut-n-pasting (especially when trying to get the performance of templated code without templates).

Quote
Is so much just to get an iterator object. Is this the only way to do this? I suppose typedef could take care of most of the labor.


Yup. C++0x I believe adds some convenience methods to make this easier. You could write your own as well using templates.

Quote
I'm afraid I just don't quite get all of C++'s quirks. Maybe that's why I'm all about learning it though!


I highly suggest you pick up the Design and Evolution of C++. It goes over the features of C++ and explains the purpose and reasoning behind each of them. Might help clear up a lot of questions you have.
12 Feb, 2010, Runter wrote in the 7th comment:
Votes: 0
JohnnyStarr said:
const char*const instanceMethod(const char*const&) const;


This is contrived to make a point, but it could come up if needed.
I guess I'm spoiled with Ruby.



Yeah, but my point is those actually mean something.

And you shoulda made it const char const * instanceMethod for good measure. :p
13 Apr, 2010, JohnnyStarr wrote in the 8th comment:
Votes: 0
Here's a quick question.

In the following function, I want to change the second parameter from (char*) to (const char*)
bool is_name ( char *str, /*char * namelist*/ const char* namelist )
{
char name[MAX_INPUT_LENGTH], part[MAX_INPUT_LENGTH];
char *list, *string;

/* fix crash on NULL namelist */
if (namelist == NULL || namelist[0] == '\0')
return FALSE;

/* fixed to prevent is_name on "" returning TRUE */
if (str[0] == '\0')
return FALSE;

string = str;
/* we need ALL parts of string to match part of namelist */
for ( ; ; ) /* start parsing string */
{
str = one_argument(str,part);

if (part[0] == '\0' )
return TRUE;
// ERROR:
@@ list = namelist;
for ( ; ; ) /* start parsing namelist */
{
list = one_argument(list,name);
if (name[0] == '\0') /* this name was not found */
return FALSE;

if (!str_prefix(string,name))
return TRUE; /* full pattern match */

if (!str_prefix(part,name))
break;
}
}
}


We wont be able to asign the pointer if it is const. How do you make not the pointer const, but what it points to const?
I need the parameter to be const so that i can send std::string.c_str() in some cases.
13 Apr, 2010, Runter wrote in the 9th comment:
Votes: 0
char * const roar;
13 Apr, 2010, David Haley wrote in the 10th comment:
Votes: 0
You just need list to be declared as a const char*, not a char*.

You can assign const char* to other const char* variables; a const char* means you can't change the contents.
14 Apr, 2010, JohnnyStarr wrote in the 11th comment:
Votes: 0
Quick question about instance members that are containers:

Because the STL provides encapsulated containers, is it conventional to use the provided public methods
alone to add / remove / sort data? Example:
ch->quests.push_back(q); /*vs*/ ch->addQuest(q); // therefor keeping (quests) private

I suppose it depends on whether or not you need to enforce constraints as to how elements are added or deleted.
Just wondering what your views were on it. One of my c++ books states:
You should make every member private unless it can be proven that it needs to be public.
14 Apr, 2010, Davion wrote in the 12th comment:
Votes: 0
JohnnyStarr said:
Quick question about instance members that are containers:

Because the STL provides encapsulated containers, is it conventional to use the provided public methods
alone to add / remove / sort data? Example:
ch->quests.push_back(q); /*vs*/ ch->addQuest(q); // therefor keeping (quests) private

I suppose it depends on whether or not you need to enforce constraints as to how elements are added or deleted.
Just wondering what your views were on it. One of my c++ books states:
You should make every member private unless it can be proven that it needs to be public.


ch->addQuest(q) definitely looks a lot cleaner! Also, it's probably better to do it this way, in case (as you said) you need to put constraints or even event triggers on items adding to a list.
14 Apr, 2010, David Haley wrote in the 13th comment:
Votes: 0
You definitely do not want to add it to the list directly. Why? That forces your implementation to be a list. Everybody has to know about your implementation. What if you later decide that internally you want something else? (For example, a mapping from quest status to quest object. Whatever…) Now you no longer have this list to act upon, and you need to rewrite a pile of code.

This is almost exactly the use case for getters and setters (or in this case, "adders") rather than pushing variables to the public scope. :smile:
14 Apr, 2010, flumpy wrote in the 14th comment:
Votes: 0
David Haley said:
You definitely do not want to add it to the list directly. Why? That forces your implementation to be a list. Everybody has to know about your implementation. What if you later decide that internally you want something else? (For example, a mapping from quest status to quest object. Whatever…) Now you no longer have this list to act upon, and you need to rewrite a pile of code.

This is almost exactly the use case for getters and setters (or in this case, "adders") rather than pushing variables to the public scope. :smile:


You're right.

Internally to a particular API implementation, it might be perfectly feasible to make the variable package/namespace protected (if you can do that in C++, I forget) and have your package classes reference it directly until you decide it's time to expose it publicly when the time's right.

Saying that you should "Always make member variables private in all circumstances" is wrong (I think that was the quote above). You certainly should not always make them "public", but thats not the same thing.
14 Apr, 2010, David Haley wrote in the 15th comment:
Votes: 0
Quote
Saying that you should "Always make member variables private in all circumstances" is wrong (I think that was the quote above). You certainly should not always make them "public", but thats not the same thing.

No, that wasn't the quote, this is why copying and pasting is useful. :tongue:

"You should make every member private unless it can be proven that it needs to be public."
(Emphasis mine.)

The point of that quote is that by default you should think "hide the variable", and only show it if you really need to (and have a clear use case).
14 Apr, 2010, flumpy wrote in the 16th comment:
Votes: 0
David Haley said:
Quote
Saying that you should "Always make member variables private in all circumstances" is wrong (I think that was the quote above). You certainly should not always make them "public", but thats not the same thing.

No, that wasn't the quote, this is why copying and pasting is useful. :tongue:

"You should make every member private unless it can be proven that it needs to be public."
(Emphasis mine.)

The point of that quote is that by default you should think "hide the variable", and only show it if you really need to (and have a clear use case).


Got it. Yea, I shud a looked again. Thx
14 Apr, 2010, JohnnyStarr wrote in the 17th comment:
Votes: 0
Thanks for the input. I also thought: what about adding / removing to the characters inventory?
If you were to be able to access the list, vector, map, etc, you wouldn't be able to control how
this would impact the character. If you were to add 100 swords that weighed 20 lbs each, this would
blow the physics out of proportion.

What seemed at first like extra work now is crystal clear that it is going to save a lot of headaches.
15 Apr, 2010, David Haley wrote in the 18th comment:
Votes: 0
Yes, the inventory question is another very good reason to have proper access methods. Imagine if somebody were to equip an item properly, such that effects were added to the character, but then unequip it by directly manipulating the equipment list – the effects would not be removed from the character! (There are other ways around this like dynamically computing effects but that's beside the point: it's quite clear that you very often want other state changes to happen when something is done to the character, and the best way to control/guarantee that is to have functions that sit as the only interface between the user and the implementation .)
16 Apr, 2010, JohnnyStarr wrote in the 19th comment:
Votes: 0
I downloaded MSVC++ 2010 Express to see how the new C++0x stuff worked.
Like David mentioned previously it allows you to do cool stuff like this:
for ( auto q = _quests.begin(); q != _quests.end(); q++ )
send((*q)->Name());

//Lambda version
std::for_each(_quests.begin(), _quests.end(), [this] (Quest *quest) { this->send(quest->Name()); });


What's nifty is this particular method is const, which means that not only does the 'auto'
know that it is a std::list< Quest * >::iterator, it knows that for this particular method it is a ::const_iterator
The lambda is just awesome if you ask me.

My question is this: Should I write my code this way going forward? In other words, is there any compliance drawbacks
here? I suppose that I would be cutting out even recent compilers for my project. Not that I personally care because I plan
to run my mud from home. But if someone wanted to run with some of my work, I guess they would have to have a C++0x compiler.
16 Apr, 2010, Runter wrote in the 20th comment:
Votes: 0
This is exactly why it hurts when you cpp.
0.0/24