JohnnyStarr
Wizard


Group: Members
Posts: 953
Joined: Feb 14, 2009
|
#1 id:41907 Posted Feb 10, 2010, 10:50 pm
|
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:
Code (C++): 1
2
3
4
5
6
7
8
9
10
11 |
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!
|
Last edited Feb 10, 2010, 10:53 pm by JohnnyStarr
|
|
|
|
JohnnyStarr
Wizard


Group: Members
Posts: 953
Joined: Feb 14, 2009
|
#3 id:41913 Posted Feb 10, 2010, 11:24 pm
|
Code (C++): 1
2
3
4
5 |
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.
|
Last edited Feb 10, 2010, 11:24 pm by JohnnyStarr
|
|
David Haley
Wizard


Group: Members
Posts: 7,783
Joined: Jun 30, 2007
|
#4 id:41916 Posted Feb 11, 2010, 1:08 am
|
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:
Code (text): 1
2
3
4 | 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:
Code (text): 1
2
3
4 | std::list<std::string> myList;
auto listItr = myList.begin(); |
Of course, C++ will probably always be a more syntax-heavy language than others.
|
|
|
|
|
elanthis
Wizard

Group: Members
Posts: 772
Joined: Feb 26, 2008
|
#6 id:41928 Posted Feb 11, 2010, 8:16 am
|
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.
|
|
......................... Cutting corners to keep your line count down is just sad.
|
|
Runter
Wizard


Group: Developer
Posts: 2,929
Joined: Jun 1, 2006
|
#7 id:41982 Posted Feb 12, 2010, 1:40 am
|
JohnnyStarr said:Code (C++): 1
2
3
4
5 |
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
|
|
|
JohnnyStarr
Wizard


Group: Members
Posts: 953
Joined: Feb 14, 2009
|
#8 id:45150 Posted Apr 13, 2010, 11:00 am
|
Here's a quick question.
In the following function, I want to change the second parameter from (char*) to (const char*)
Code (c): 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 |
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.
|
|
|
|
|
|
|
JohnnyStarr
Wizard


Group: Members
Posts: 953
Joined: Feb 14, 2009
|
#11 id:45165 Posted Apr 13, 2010, 7:51 pm
|
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:
Code (c++): 1
2
3 | 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.
|
Last edited Apr 13, 2010, 7:52 pm by JohnnyStarr
|
|
Davion
Idle Hand


Group: Administrators
Posts: 1,537
Joined: May 14, 2006
|
#12 id:45167 Posted Apr 13, 2010, 9:07 pm
|
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:
Code (c++): 1
2
3 | 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.
|
......................... 
|
|
|
|
flumpy
Wizard


Group: Members
Posts: 623
Joined: Mar 27, 2009
|
#14 id:45210 Posted Apr 14, 2010, 12:31 pm
|
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. 
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.
|
Last edited Apr 14, 2010, 12:32 pm by flumpy
|
|
|
|