C++ Getters/Setters Coding Style

Conventions for accessor methods (getters and setters) in C++

From my perspective as sitting with 4 million lines of C++ code (and that's just one project) from a maintenance perspective I would say:

  • It's ok to not use getters/setters if members are immutable (i.e. const) or simple with no dependencies (like a point class with members X and Y).

  • If member is private only it's also ok to skip getters/setters. I also count members of internal pimpl-classes as private if the .cpp unit is smallish.

  • If member is public or protected (protected is just as bad as public) and non-const, non-simple or has dependencies then use getters/setters.

As a maintenance guy my main reason for wanting to have getters/setters is because then I have a place to put break points / logging / something else.

I prefer the style of alternative 2. as that's more searchable (a key component in writing maintainable code).

C++ getters/setters coding style

It tends to be a bad idea to make non-const fields public because it then becomes hard to force error checking constraints and/or add side-effects to value changes in the future.

In your case, you have a const field, so the above issues are not a problem. The main downside of making it a public field is that you're locking down the underlying implementation. For example, if in the future you wanted to change the internal representation to a C-string or a Unicode string, or something else, then you'd break all the client code. With a getter, you could convert to the legacy representation for existing clients while providing the newer functionality to new users via a new getter.

I'd still suggest having a getter method like the one you have placed above. This will maximize your future flexibility.

C++ getters and setters best style

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.

Getters and setters in pure C?

First of all, don't listen to anyone saying "there is no object-orientation in language x" because they have truly not understood that OO is a program design method, completely apart from language syntax.

Some languages have elegant ways to implement OO, some have not. Yet it is possible to write an object-oriented program in any language, for example in C. Similarly, your program will not automagically get a proper OO design just because you wrote it in Java, or because you used certain language keywords.

The way you implement private encapsulation in C is a bit more crude than in languages with OO support, but it does like this:

// module.h

void set_x (int n);
int get_x (void);

// module.c

static int x; // private variable

void set_x (int n)
{
x = n;
}

int get_x (void)
{
return x;
}

// main.c

#include "module.h"

int main (void)
{
set_x(5);
printf("%d", get_x());
}

Can call it "class" or "ADT" or "code module" as you prefer.

This is how every reasonable C program out there is written. And has been written for the past 30-40 years or so, as long as program design has existed. If you say there are no setters/getters in a C program, then that is because you have no experience of using C.

getters and setters style

I would prefer the get/set versions because it is more clear as to what is going on. If I saw rate() and rate(10), how do I know that rate(10) isn't simply using 10 in the calculation to return the rate? I don't, so now I have to start searching to figure out what is going on. A single function name should do one thing, not two opposing things.

Also, as others have pointed out, some prefer to omit the 'get' and leave the 'set', i.e.,

int Rate( );
void SetRate( int value );

That convention is pretty clear as well, I wouldn't have any problem reading that.

How to write C++ getters and setters

There are two distinct forms of "properties" that turn up in the standard library, which I will categorise as "Identity oriented" and "Value oriented". Which you choose depends on how the system should interact with Foo. Neither is "more correct".

Identity oriented

class Foo
{
X x_;
public:
X & x() { return x_; }
const X & x() const { return x_; }
}

Here we return a reference to the underlying X member, which allows both sides of the call site to observe changes initiated by the other. The X member is visible to the outside world, presumably because it's identity is important. It may at first glance look like there is only the "get" side of a property, but this is not the case if X is assignable.

 Foo f;
f.x() = X { ... };

Value oriented

class Foo
{
X x_;
public:
X x() const { return x_; }
void x(X x) { x_ = std::move(x); }
}

Here we return a copy of the X member, and accept a copy to overwrite with. Later changes on either side do not propagate. Presumably we only care about the value of x in this case.

How to Write Getters and Setters for C-Style String Array?

Since the length of the name in your class is a fixed length, the easiest way to do this std::strncpy. That would work as follows:

inline void Unit::SetName (char const * name) {
std::strncpy(this->name, name, UnitNameSize);
// Ensure name member ends in null-terminator,
// even if new name length is >= UnitNameSize.
this->name[UnitNameSize - 1] = 0;
}

c# getters setters style

There's no reason for code like that as far as I can see. If you're not doing anything with the new values (like processing/checking before storing) and you're writing C# 3.0 you can actually just shorthand it it to this:

public int MyProperty { get; set; }

The compiler creates the backing store for you and you can just reference:

this.MyProperty

...inside your class. You can also create get-only properties like:

public int MyProperty { get; private set; }

All of which I think is pretty neat!

Getter & Setter in C++/C project?

I am a not expert, but isn't it too complicated to generate C++/C functions and replace your variable by some macro ?
Your a bit modified version:

#ifdef __cplusplus
#define TRACK_C(a, b) \
extern "C" a _get$##b() { \
return b; \
}; \
extern "C" void _set$##b(a c) { \
##b = c; \
};
#define TRACK_PROP(a,b) TrackProp<a> b(#b); \
TRACK_C(a, b)
#define TRACK_PROP_SET(a,b,c) TrackProp<a> b(#b, c); \
TRACK_C(a, b)
template <class T>
class TrackProp {
public:
T _content;
const char* Name;

TrackProp(const char* name) { Name = name; }
TrackProp(const char* name, T val) { Name = name; _content = val; }
T operator =(T right)
{
if (_content != right) {
cout << Name << ":" << _content << "->" << right << endl;
_content = right;
}
return _content;
}

operator T() const
{
return _content;
}
};
#else
#define TRACK_C(a,b) \
a _get$##b(); \
void _set$##b(a);
#define TRACK_GET(b) _get$##b()
#define TRACK_SET(b,c) _set$##b(c)
#endif

In C++ you can still use you operators

#include <iostream>
#include "TRACK_PROP.h"

using namespace std;

TRACK_PROP(int, demo);

extern "C" void test();

void main(void) {
demo = 123;
cout << demo;
test();
}

And in C replace a demo variable use by my macros:

#include "TRACK_PROP.h"

TRACK_C(int, demo)

void test() {
// demo = 1
TRACK_SET(demo, 1);
// demo = 3*demo;
TRACK_SET(demo, 3*TRACK_GET(demo)));
}

It would be great if there will be easier option, but I do not know about any direct way too...



Related Topics



Leave a reply



Submit