#75675 - tepples - Wed Mar 15, 2006 3:40 am
In Using more C++ files, genfish wrote: |
Code: |
#ifndef CExample_h
#define CExample_h
class CExample
{
public:
int a,b;
CExample();
~CExample();
private:
bool ExampleFunc(int a);
};
#endif
|
|
What's the reason for prefixing all class names with a C? Isn't the initial capital letter enough to distinguish a class from something else? And doesn't it create confusion with #include <cstdlib>, etc., where the initial 'c' denotes that the header was inherited from the C language?
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#75676 - slip - Wed Mar 15, 2006 3:44 am
Yeah, i think so too. It's just a matter of preference i guess, but some people do it because thats how they've seen it done. So it wouldn't surprise me that some also think the 'C' is required. *shrug*
_________________
[url="http://www.ice-d.com"]www.ice-d.com[/url]
#75678 - gauauu - Wed Mar 15, 2006 4:25 am
The same reason that in Delphi's VCL and other code, they use the standard of prefixing all classes with T.
Crazy talk, if you ask me. But to each his own.....as long as nobody gets onto me for not using the one-true-brace-style ;-)
#75689 - sumiguchi - Wed Mar 15, 2006 5:48 am
Personally I like to prefix my classes with a C just so I can diferentiate between the class and the instantiation of the class.
#75692 - tepples - Wed Mar 15, 2006 5:56 am
I'm just used to Sun's conventions for C, C++, and Java, in which names of objects (instances of a class) start with a lowercase letter. For instance:
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#75694 - poslundc - Wed Mar 15, 2006 5:59 am
tepples wrote: |
What's the reason for prefixing all class names with a C? Isn't the initial capital letter enough to distinguish a class from something else? |
I've pretty much adopted the convention in my own work. There are some useful advantages the conventions can provide:
- Prefixing with an "I" instead of "C" can be used to distinguish interfaces from classes, since C++ doesn't make the distinction itself.
- I don't use the prefix if I'm declaring a struct. By naming structs differently from classes, it keeps it more apparent where encapsulation and OO behaviour is integral to the design. (I know some people use the "S" prefix for structs... I find that just a plain capital letter is sufficient. YMMV.)
Especially when working in a team environment where people have different levels of experience with and understanding of OO methodologies, maintaining a consistent convention can help reinforce weak links. I like to think that when someone sees the "C" prefixing one of my classes, they know more intuitively that they are expected to use accessor methods when dealing with its contents, rather than just going in and making everything public or what-have-you.
Quote: |
And doesn't it create confusion with #include <cstdlib>, etc., where the initial 'c' denotes that the header was inherited from the C language? |
Lowercase "c". *shrug*
Dan.
#75695 - DekuTree64 - Wed Mar 15, 2006 6:32 am
My preferred naming conventions:
Code: |
THIS_IS_A_CONSTANT_OR_MACRO
gThisIsAGlobalVariable
thisIsALocalVariable
ThisIsAFunction (global or static, no difference)
ThisIsAStruct (same as function, usually doesn't cause trouble)
{
thisIsAStructMember; (same as local vars)
};
CThisIsAClass (easier to tell a constructed variable apart from a function call)
{
ThisIsAMemberFunction();
m_thisIsAMemberVariable;
};
this_is_a_goto_label: (mainly for assembly)
rThisIsARegister (for assembly, I #define registers that hold a consistent value) |
I really don't care that much though. I usually just follow the conventions of the surrounding code, unless I'm starting an entirely new project from scratch.
The original message does have one thing that annoys me though, which is prefixing filenames with C. It makes logical sense to have the filename the same as the class it contains, but for some reason I just don't like it.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku
#75696 - sajiimori - Wed Mar 15, 2006 6:42 am
Our structs/classes cover the entire gradient from plain C-style structs to fully encapsulated objects, from nothing but pure virtuals to nothing but concrete methods. There is no particular place to draw the line between a "struct" and a "class".
And if we were to choose some arbitrary method of distinguishing structs from classes, there will always be types that linger near the borderline. Shall we rename the type and edit all the client code every time it crosses that line?
Why should the client code depend on whether there happens to be a method or a piece of private data, even if the client doesn't interact with that portion of the interface (or non-interface, in the case of private data)?
#75719 - sgeos - Wed Mar 15, 2006 1:57 pm
I think that differentiating between interfaces and classes at the "user" level could be dangerous. Just pass types. A type may be a class or an interface or a struct or something else. Having to change the type name when the internal details change is bad.
I'll admit that there are times when I'll break a class into an implementation and an interface because I want to recycle the name:
Code: |
interface IApple
{
// interface
}
class Apple implements IApple
{
// lotsa-data
}
class PolymorphicApple implements IApple
{
// no data; all returns are random
} |
These are my current naming conventions:
Code: |
type_t gGlobalVariable; // rarely used
type_t mModuleVariable; // often used
return_t functionName
(
type_t pParameter // parameters are read only
)
{
type_t localVariable;
}
class ClassName
{
type_t mPrivateVariable;
type_t publicVariable; // use this.publicVariable in the class
return_t methodName
(
type_t pParameter // parameters are read only
)
{
type_t localVariable;
}
} |
I have no convention for class variables (I've not yet had a reason to use them). I welcome general constructive criticism.
-Brendan
#75743 - poslundc - Wed Mar 15, 2006 5:53 pm
sajiimori wrote: |
Our structs/classes cover the entire gradient from plain C-style structs to fully encapsulated objects, from nothing but pure virtuals to nothing but concrete methods. There is no particular place to draw the line between a "struct" and a "class". |
The simplest line to draw is which keyword you decide is more appropriate to use when declaring it in C++. ;)
(If that seems like it evades the question, the point is to use whichever tool is best suited the problem you are solving, not to establish hard and arbitrary rules that can be used to govern every imaginable situation.)
Quote: |
And if we were to choose some arbitrary method of distinguishing structs from classes, there will always be types that linger near the borderline. Shall we rename the type and edit all the client code every time it crosses that line? |
Not unless that kind of refactoring is going to be sufficiently beneficial down the line to be worth the time spent doing it now. I think so long as a system is being consistent in its design, though, it probably isn't adviseable.
Quote: |
Why should the client code depend on whether there happens to be a method or a piece of private data, even if the client doesn't interact with that portion of the interface (or non-interface, in the case of private data)? |
Because programmers aren't robots, and ideas and design patterns aren't always adequately conveyed through a spec alone. When code is being shared with a team, it's important to be as communicative as possible, and adopting coding conventions that are meaningful to you (as opposed to just ritual) can help with that.
Dan.
#75745 - poslundc - Wed Mar 15, 2006 6:00 pm
sgeos wrote: |
I think that differentiating between interfaces and classes at the "user" level could be dangerous. Just pass types. A type may be a class or an interface or a struct or something else. Having to change the type name when the internal details change is bad. |
I waver on this. I think refactoring often generates client code change as a necessary side-effect, so doing things that will minimize that kind of code change is probably a Good Thing.
I don't think exposing it is dangerous, though... in fact, I think exposing the structural hierarchy of your design is also a Good Thing. It just depends on what's more important to the environment you're developing in.
Dan.
#75760 - sajiimori - Wed Mar 15, 2006 7:57 pm
Quote: |
The simplest line to draw is which keyword you decide is more appropriate to use when declaring it in C++. ;) |
Then at best the extra letter says nothing and at worst it has a meaning that differs between every programmer on your team, as they each draw their own personal line. (Speaking of having consistent standards!)
Quote: |
(If that seems like it evades the question, the point is to use whichever tool is best suited the problem you are solving, not to establish hard and arbitrary rules that can be used to govern every imaginable situation.) |
The "class" and "struct" keywords are not different tools that solve different problems, and a capital "C" is not a tool that solves a problem (except in the circular argument that it distinguishes classes from structs), so I don't understand your point about choosing the right tools.
Quote: |
I think so long as a system is being consistent in its design, though, it probably isn't adviseable [to add and remove 'C's]. |
Consistent in what? Obviously not in naming conventions. Or wait, you said the name you choose is right by definition, because it becomes right by virtue of the fact that the author chose it? That is a very consistent convention, but it conveys no information to the reader besides some historical detail about how the author felt about the original implementation at the time of its inception.
Quote: |
When code is being shared with a team, it's important to be as communicative as possible, and adopting coding conventions that are meaningful to you (as opposed to just ritual) can help with that. |
And the convention you suggest is not meaningful. It only applies to one person -- the author -- because there is no consistent mechanism for deciding how to apply the convention and each person may have a different idea. It doesn't even provide information about the present; it's a historical piece of information that can be invalidated by changes over time.
Quote: |
Having to change the type name when the internal details change is bad. |
This is what I'm saying! :)
#75761 - DekuTree64 - Wed Mar 15, 2006 8:02 pm
I prefer structs to always be data-only. Sort of making the distinction that structs are just a group of variables, and classes cover all other uses.
I would like to hear some opinions on what sort of situation a struct would be more appropriate than a class and vice versa. If there's no functional difference between the two, then why not just pick one and stick to it through all your code?
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku
#75764 - sajiimori - Wed Mar 15, 2006 9:01 pm
I'll use the struct keyword as a shortcut for typing "public:", but that's about it. There might be some types lingering in our project that use the struct keyword and also have private data, but I don't really care -- and the client code doesn't care, either. :)
#75766 - poslundc - Wed Mar 15, 2006 9:04 pm
sajiimori wrote: |
Quote: | The simplest line to draw is which keyword you decide is more appropriate to use when declaring it in C++. ;) |
Then at best the extra letter says nothing and at worst it has a meaning that differs between every programmer on your team, as they each draw their own personal line. (Speaking of having consistent standards!) |
Having a prefix that reflects the primitive keyword used in the declaration does not "say nothing" at best; at the very least it says what that primitive was without having to look it up in the declaration. At a higher level, it can also provide a clue and/or reminder as to where the object fits into the design pattern.
Whether it provides that clue or not depends on the programmer who coded the system, the programmer reading the code, and the nature of the system itself. But while clues can go missing or unused they are very rarely misinterpreted... at least, I've never heard anyone who thought "he used a struct instead of a class; clearly encapsulated behaviour is the focus here instead of storage".
Quote: |
The "class" and "struct" keywords are not different tools that solve different problems, and a capital "C" is not a tool that solves a problem (except in the circular argument that it distinguishes classes from structs), so I don't understand your point about choosing the right tools. |
I'm not about to get into the argument with you again that programming semantics have an effect that goes beyond what they are translated to by the compiler. The use of "struct" and "class" keywords do convey different meanings and serve different purposes when used in different coding contexts in different systems; if you choose to believe that isn't the case then there's nothing I can say except you ought to spend more time working with other people's code, because not everyone writes code the same way you do.
Quote: |
Or wait, you said the name you choose is right by definition, because it becomes right by virtue of the fact that the author chose it? |
No, there is no right and wrong here, there's only what makes sense and what is useful.
Code around the world wouldn't be made universally easier to follow if every programmer everywhere was forced to suck up their individual preferences and followed Hungarian notation exclusively and unwaveringly, applying it the exact same way in every language and every application. Odds are it would make things far, far worse overall. This does not mean that Hungarian notation can't be useful, though.
Quote: |
That is a very consistent convention, but it conveys no information to the reader besides some historical detail about how the author felt about the original implementation at the time of its inception. |
You can paint it that way if you choose. Again, spend some time deciphering code that was written years ago by people with varying levels of experience who are no longer around to explain it. Every clue matters, and consistent naming conventions can go a long way when you're following breadcrumbs.
Quote: |
Quote: | When code is being shared with a team, it's important to be as communicative as possible, and adopting coding conventions that are meaningful to you (as opposed to just ritual) can help with that. |
And the convention you suggest is not meaningful. It only applies to one person -- the author -- because there is no consistent mechanism for deciding how to apply the convention and each person may have a different idea. |
If I am consistent in how I apply a convention, and if that convention makes sense, the convention will be meaningful to anyone reading my code.
Not everyone has to apply the same conventions in the same way to understand how and why others use their conventions.
Quote: |
It doesn't even provide information about the present; it's a historical piece of information that can be invalidated by changes over time. |
I don't understand what you're saying here. If the convention I personally use that I described in the previous post is applied to a system that I write, then it can be used to better understand the system at any point in time. If the entire system is overhauled and refactored and changed around then obviously the names may require changing to keep the convention applied consistently, but this is a normal part of the refactoring process.
Quote: |
Quote: | Having to change the type name when the internal details change is bad. |
This is what I'm saying! :) |
I don't deny that it's a drawback. But it's not the only consideration, either, and it's not something you're guaranteed to avoid by not adopting a convention in the first place.
Dan.
#75768 - poslundc - Wed Mar 15, 2006 9:09 pm
sajiimori wrote: |
I'll use the struct keyword as a shortcut for typing "public:", but that's about it. |
So when you apply this shortcut, are you not indicating an aspect of the design when you do so?
Do you not think that I or someone else would be able to comprehend this indication, even if we don't apply that same convention to our code?
Dan.
#75770 - sajiimori - Wed Mar 15, 2006 9:27 pm
I don't have time to debate with non sequiturs and nitpicks.
Quote: |
So when you apply this shortcut, are you not indicating an aspect of the design when you do so? |
No, I am not.
Edit:
Quote: |
...you ought to spend more time working with other people's code, because not everyone writes code the same way you do. |
I'm not going to pander to deficiencies and misconceptions. Call it tough love, but the moment I become complacent is the moment I quit this job.
Last edited by sajiimori on Wed Mar 15, 2006 9:36 pm; edited 1 time in total
#75771 - sumiguchi - Wed Mar 15, 2006 9:33 pm
Quote: |
I'm just used to Sun's conventions for C, C++, and Java, in which names of objects (instances of a class) start with a lowercase letter. |
True, when in Java, I generally follow this convention.
For C++, generally follow Hungarian notation.
Quick reference -> http://web.umr.edu/~cpp/common/hungarian.html
Last edited by sumiguchi on Wed Mar 15, 2006 9:36 pm; edited 1 time in total
#75772 - poslundc - Wed Mar 15, 2006 9:35 pm
sajiimori wrote: |
I don't have time to debate with non sequiturs and nitpicks. |
But you have time to criticize the structure of my argument without providing specific example? That's mighty convenient.
Quote: |
Quote: | So when you apply this shortcut, are you not indicating an aspect of the design when you do so? |
No, I am not. |
We disagree on that.
Dan.
#75774 - sajiimori - Wed Mar 15, 2006 9:39 pm
Quote: |
But you have time to criticize the structure of my argument without providing specific example? That's mighty convenient. |
Isn't it, though?
#75776 - poslundc - Wed Mar 15, 2006 9:44 pm
It is. It also doesn't fabricate any credence to what you say.
Spare me the bull. If you don't have time to debate then that's fine, but don't expect me to take a parting potshot lying down.
Dan.
#75804 - tepples - Thu Mar 16, 2006 4:11 am
Prefixing based on data type is Systems Hungarian, not Hungarian notation as Charles Simonyi conceived it. There's a difference.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.