2

in Java code convention is simple and obvious, in this style:

public:
    int GetMyAge(){
        return myAge;
    }
    void SetMyAge(int myAge){
        this->myAge = myAge;
    }
private:
    int myAge;

(I know it's "again the same thing", but) I have read most of related questions on SO and I still don't know "the best one" and "the most official" way to do it in C++. It can't be just a matter of preferences, can it?

EDIT:

Seems like it can.

dantuch
  • 9,123
  • 6
  • 45
  • 68
  • possible duplicate of http://stackoverflow.com/q/1610029/11343 – CharlesB Apr 26 '11 at 09:15
  • @CharlesB, yes, and the best answer there is opposite to answers here http://stackoverflow.com/questions/760777/c-getters-setters-coding-style that's why it's not clear for me witch one to use – dantuch Apr 26 '11 at 09:21
  • 1
    @CharlesB that also is dealing with a constant, which we aren't here. Although it does bring in a good point - these are simple things that can be `inline`d although they're so small I can't imagine any compiler worth its salt wouldn't inline it for you (considering the `inline` modifier is only a suggestion anyway.) – corsiKa Apr 26 '11 at 09:26
  • @dantuch the fact that there's several different answers show that glowcoder is right: *your* style is the best, no official guidelines in C++ – CharlesB Apr 26 '11 at 09:28
  • 1
    Coding-Style are subjective, this question is better suited to Programmer SE. – Matthieu M. Apr 26 '11 at 09:28
  • That's **not** Java coding convention (Java normally uses `camelCase`). – Jan Hudec Apr 26 '11 at 09:29
  • @Jan Hudec, true, anyway - I tried to make C++ style form Java's :) that's why there are upper cases as first letters of methods – dantuch Apr 26 '11 at 09:35
  • @dantuch: It seems like persons with strong convictions already have answered your question. I just want to add that, in Java as far as I know, the empasis is laid on consistent patterns e.g. always getter and setters. When writing C++ one is more interested with expressing intent (as the Guru always says). If no setters, tells, you welcome to look at it but don't touch. If getter and setters set what you want but I will check them for you. If public variable, it happens, do what you want, have fun, but don't blame me when things go wrong. –  Apr 26 '11 at 09:44
  • @dantuch: Upper-case first letters is Microsoft style and the rest of the world generally dislikes it. If anything can be called "official", it would be the style of standard library and that uses "lower_case" for everything including types. – Jan Hudec Apr 27 '11 at 05:10
  • @Jan Hudec, oh God... I was sure, that I have to start methods with upper-case letters :X even *GoF - D-P* has this style... anyway, now I see, that *Effective C++* uses camelCase :(. Thanks a lot :) – dantuch Apr 27 '11 at 06:12

4 Answers4

12

Best not to do it at all. Can your age actually be changed like that? Blindly providing getters and setters for all properties is a sign you have not designed your class properly.

  • 1
    About your last sentence, `[citation needed]` It would be nice to think that we could always deal with immutable classes/objects. But we can't, and we won't. Besides - some things do change. Consider a Player object in a game who changes position. – corsiKa Apr 26 '11 at 09:12
  • @glowcoder Most classes are immutable in many ways. Consider a BankAccount - can you change the account number? No, but you can change the account holders name. My point is that blindly writing getters and setters is bad practice. –  Apr 26 '11 at 09:16
  • @unapersson: most people here will agree with you. However, there are cases where you must write a getter, and even sometimes, God forbid, a setter. – Alexandre C. Apr 26 '11 at 09:18
  • See http://stackoverflow.com/questions/737409/are-get-and-set-functions-popular-with-c-programmers/737552#737552 for an argumentation to evil getters/setters – CharlesB Apr 26 '11 at 09:18
  • @unapersson "Do it judiciously" (what you imply with your last sentence in the comment) and "not to do do it at all" (what you say in your first sentence in your post) are two very different things. – corsiKa Apr 26 '11 at 09:19
  • @glowcoder The first sentence refers to the practice of providing GetX and SetX functions. Even if your class properties are mutable you should never (IMHO) name their accessor functions like this. –  Apr 26 '11 at 09:26
  • @unapersson Any particular reason for that? – corsiKa Apr 26 '11 at 09:28
  • 1
    @glowcoder: The use of getters/setters is plain and simple bad design. Unfortunately real world does not always allow us to do the perfect design. Note: Just because an object does not have getters and setters does not mean it is immutable. A player can move because it has the method `move()` on it rather than exposing the X/Y coordinates via getters and setters. Exposing the internals of the class is breaking encapsulation (even when done by getters) as you introducing an interface that now must be maintained. methods should (preferably) by verbs that act on the state of the object. – Martin York Apr 26 '11 at 09:31
  • cont ... Example 2: You pass the stream to the object so that it can serialize/de-serialize itself to/from the stream. You do not need to expose its internal state to the world so that it can be serialized in 15 different ways by 15 different other developers all writing their own serialization class. – Martin York Apr 26 '11 at 09:32
  • @Martin I agree with many points. I do not feel that getters and setters are simply poor design. What alternative would you suggest for `player.getPosition()`? I'm not suggesting that you expose more than you need to. Obviously some behavior needs to be exposed (wouldn't be useful otherwise) and I see plenty of room for maintainable code with judicious use of getters and setters. It does not require that you code it up like an entity bean with more getters and setters than you can shake a stick at. – corsiKa Apr 26 '11 at 09:34
  • 2
    I would suggest that you don't need `getPosition()`. The question is why do you need the position? To draw the player on the board? Then you should have a `draw()` method that you pass the board/screen object. Is it because you want to serialize it? Then you should have a `serialize()` method that you pass a stream too. etc. getters/setters tightly coupling the design of the object to the code that uses the object. You want to break the coupling by putting the code that manipulates the object into the object. – Martin York Apr 26 '11 at 09:40
  • @glowcoder, @Martin - using interfaces doesn't solve all those problems? Then only behavior is exposed and getters and setters are hidden somewhat (ofc. not every class needs interface, but the most important once should). – dantuch Apr 26 '11 at 10:32
  • @Martin if you want a draw method, then you need to pass in some canvas to draw on as you mentioned. How would you draw your player without being able to acquire information about said canvas? There are times where some getters (and even setters) are useful and appropriate. The canvas's getHeight() and getWidth() methods are prime examples of some things you just need to know to position components around your screen. – corsiKa Apr 26 '11 at 15:14
  • @glowcoder: again not true. Tightly coupling your object to usage is just bad design. You need to ask yourself why am I exposing this. If the reason is because I want to perform som calculation then store the value back then you are doing it WRONG. Operations should be done within the class thus loosely coupling the objects yhe usage poi ts with a well defined interface. Getters/setters tightly couple yhe object. – Martin York Apr 26 '11 at 15:56
  • @Martin then I guess Swing, AWT, GWT, SWT, and OpenGL all did it wrong. Them and their shoddy practices... :-( – corsiKa Apr 26 '11 at 16:36
  • @glowcoder: Swing/AWT/GWT/SWT are all Java libraries. Java libraries have a tendency to overuse getters/setters because of reflection and its use in serialization. So this is relatively normal for Java. But this question is about C++. Also you seem to have pulled a set of windowing libraries. I would say that is OK given the usage. But you keep diverting from the main point to try and win an argument you already lost. **You need to ask yourself why am I exposing this** In 99% of cases you will find it is a mistake an **tightly couples** your code to the object. In Windowing librs thats normal. – Martin York Apr 26 '11 at 17:43
  • @Martin off the top of my head I can think of reporting mechanisms that would require the ability to query data from what it's reporting on, I can think of order-entry where you often need to make modifications to the order, in **most** cases in my daily work, I see the need to **require** the (judicious) use of setters and getters. And the reasons for requiring this are language agnostic. – corsiKa Apr 26 '11 at 17:50
  • @glowcoder: Both of those senarios are wrong. In the reporting system the object should be able to report its own data (when passed a report object). `out<<"Bad Obj";Obj.report(out);` The order entry system you should be asking the order to modify itself. `order.delete(Coffie); order.add(Beer);` These are classic mistakes in my opinion. Note: I also said in my fist comment: **Unfortunately real world does not always allow us to do the perfect design.** – Martin York Apr 26 '11 at 18:18
5

The best style is the one that allows you and your team to make quality software that your clients continue to pay you for.

How does this style work for you and your team? Do you find it causes (or prevents) bugs? Do you find it easy to maintain the code? Do you bicker about the formatting?

Answer those questions and the answer to your question will arise out of them.

corsiKa
  • 81,495
  • 25
  • 153
  • 204
  • 1
    @Downvoter care to comment on how this answer can be improved? – corsiKa Apr 26 '11 at 09:25
  • 3
    -1: This answer provides no help at answering the question as it is too general. Making software badly may get things done in the short run but will bankrupt you and your customers quickly if they have to maintain shoddy code produced by over generalized style that does not follow good practice. – Martin York Apr 26 '11 at 09:36
  • @Martin any software company doing their due diligence will analyze their software production standards (naming conventions, style guides, build routines, test plans, deployment procedures, etc...) and identify those that are causing problems (bugs, increased maintenance times, performance bottlenecks, internal warfare, etc...) - the truth of the matter is we can preach until we're blue in the hyperlinks, **there are no best practices in the real world**. There's what works with individual companies, and teams within those companies. Your religious objection to ever using a set/get is noted. – corsiKa Apr 26 '11 at 15:22
  • My favorite part about most of these coding-style questions is that the best answers are rarely ones that advocate one specific doctrine. – Tony Lukasavage Apr 27 '11 at 15:08
0

A simple answer: class names are capital in general in c++ (except for the std classes), methods are lower case, some frameworks like Qt prefer camelCase, however I prefer underscore_notation -- and so do the STL see eg. "auto_ptr".

Classes do not always have separate .h files, because here a .java file is split up into a .h header (for an entire package), and .cpp implementation files, one per class.

class TipicalCamelCase {
public:
    /// mark the frequently used small functions inline in the class def.
    inline int getMyAge() const;
    void setMyAge(int myAge=5); // defaults go to the definition.

    /// for efficiently setting more complex things.
    void setMyStuff(const MyStuff& myStuff); 

    /// a tipical class-valued getter 
    /// (sometimes scoffed at since it can have memory leaks 
    /// if you dismiss the class but still use and don't copy MyStuff.)
    const MyStuff& getMyStuff() const; 

    /// a safe getter, but forces copying-out MyStuff.
    MyStuff getMyStuff() const; 

private:
    int myAge;
    static const int zero=0; // allowed only in the new C++11 standard.
    static const int one;
};

Some implementations/initializations (usually in separate TipicalCamelCase.cpp file):

const int TipicalCamelCase::one = 1;

int TipicalCamelCase::getMyAge() const{
    return myAge;
}
void TipicalCamelCase::setMyAge(int myAge_){
    myAge = myAge_;
}

Underscore style is the same but

int Tipical_camel_case::get_my_age() const
{
    return my_age;
}

I prefer this as it looks cleaner both in the header and in the implementation files. You can see that function headlines are lengthier than in java. Especially you'll see with templates (generics) 2 lines' header is typical, so it is worth to put them a bit more separated.

template<typename _Tp>
int Class_name::general_function(_Tp);

I think it should do as a style intro. If you use inheritance, for the java-style working, mark every function except the constructors virtual so that the @overrides behave correctly.

Barney Szabolcs
  • 11,846
  • 12
  • 66
  • 91
-5

What you have written in the above code is a correct syntax . If you are looking for a thumb rule, code your acccessor functions in such a way that they are set / get exactly the values .

EG :

void SetMyAge(int newAge)
{
    if(newAge > 10 && newAge < 100)
       _age = newAge ;
}

I would prefer to put the validation "newAge > 10 && newAge < 100" in a different function, IsValidAge ; even if the code is just one line. On the long run, small functions help in maintaining the code, and helps new developers to understand the code better.

void SetMyAge(int newAge)
{
    if(IsValidAge() )
       _age = newAge ;
}

However I would like to comment on this

void SetMyAge(int myAge){
    this->myAge = myAge;
 }

It is good practice to differentiate the nameing convention of the class varaiable to _myAge .

EDIT I think the variable name was comprehended improperly .

myAge should be named _myAge .

Sujay Ghosh
  • 2,828
  • 8
  • 30
  • 47
  • 4
    `int int_myAge`? oh please, c’mon… – knittl Apr 26 '11 at 09:17
  • 1
    @glowcoder Hungarian notation would have made it to nMyAge . Appending _ to a variable name is common practice, referring to class visibility. – Sujay Ghosh Apr 26 '11 at 09:26
  • 2
    @Sujay Appending, possibly. Prepending, no. –  Apr 26 '11 at 09:29
  • @Sujay There are a number of forms of Hungarian notation. A common one is appending `_` or `m_` to member variables. Any IDE worth its salt will color-code your variables for you, and it will never forget to do so like a name convention will. – corsiKa Apr 26 '11 at 09:29
  • I don't like your first setter. It'll fail silently not letting the user/programmer know why the property is not being set. – RedX Apr 26 '11 at 09:32
  • @RedX, I agree with you. stter should allways work the same - set value. That logic should be moved outside. – dantuch Apr 26 '11 at 09:38
  • @RedX That was a small sample. My emphasis was on keeping the IsValidAge seperate from the SetAge code. – Sujay Ghosh Apr 26 '11 at 09:40