How to Write C++ Getters and Setters

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.

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.

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...

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).

Setters and getters in C++

It's the exact same thing. In Java if you had named your parameter c instead of color, you would not have any shadowing and you could easily write

void setColor(String c) {
color = c;
}

The this in Java (or C++ for that matter) is only needed to specify exactly which color you are referring to: the member variable or the local variable.

Simple C++ getter/setters

  • Generally using accessors/mutators at all is a design smell that your class public interface is incomplete. Typically speaking you want a useful public interface that provides meaningful functionality rather than simply get/set (which is just one or two steps better than we were in C with structs and functions). Every time you want to write a mutator, and many times you want to write an accessor first just take a step back and ask yourself "do I *really* need this?".
  • Just idiom-wise people may not be prepared to expect such a function so it will increase a maintainer's time to grok your code.
  • The same-named methods are almost the same as the public member: just use a public member in that case. When the methods do two different things, name them two different things.
  • The "mutator" returning by non-const reference would allow for a wide variety of aliasing problems where someone stashes off an alias to the member, relying on it to exist later. By using a separate setter function you prevent people from aliasing to your private data.

How do I write setters and getters for an array? (c++)

string name[];

This is not an array, it is a pointer. Use vectors instead:

#include <vector>
class planet: public body
{
private:
vector<string> name;
vector<string> star;
public:
void nameSetter (const vector<string> &h_name)
{
name = h_name;
}
};

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;
}


Related Topics



Leave a reply



Submit