Question: I'm coming to C++ from C# and const-correctness is still new to me. In C# I could declare a property like this:

```
class Type 
{
    public readonly int x;
    public Type(int y) 
    {
        x = y;
    }
}

```

This would ensure that x was only set during initialization. I would like to do something similar in C++. The best I can come up with though is:

```
class Type
{
private:
    int _x;
public:
    Type(int y) { _x = y; }
    int get_x() { return _x; }
};

```

Is there a better way to do this? Even better: Can I do this with a struct? The type I have in mind is really just a collection of data, with no logic, so a struct would be better if I could guarantee that its values are set only during initialization.

Answer: 
Rather than a collection of constants, you could have a constant collection. The property of being constant seems to pertain to your use case, not the data model itself. Like so:

```
struct extent { int width; int height; };

const extent e { 20, 30 };

```

It's possible to have specifically constant data members of a class, but then you need to write a constructor to initialize it:

```
struct Foo
{
    const int x;
    int & y;
    int z;

    Foo(int a, int & b) : x(a + b), y(b), z(b - a) {  }
};

```

(The example also shows another type of data member that needs to be initialized: references.)

Of course, structs and classes are the same thing.
This is not exactly answering the question asked, but if you wanted to have the simplicity of directly accessing member variables in a struct without getters, but wanted to ensure that nobody could modify the values, you could do something like this:

```
#include <iostream>

using namespace std;

class TypeFriend;

struct Type
{
  const int &x;
  const int y;

  Type (int vx, int vy):x (_x), y (vy), _x (vx)
  {
  }

private:
  friend class TypeFriend;
  int _x;

};

struct TypeFriend
{
  TypeFriend (Type & t):_t (t)
  {
  }

  void setX (int newX)
  {
    _t._x = newX;
  }

private:
  Type & _t;
};

int main ()
{
  Type t (1, 2);
  TypeFriend tf (t);

  cout << t.x << "," << t.y << endl;

  // t.x = 6;  // error: assignment of read-only location ‘t.Type::x’
  // cout<<t.x << ","<<t.y<<endl;

  tf.setX (5);
  cout << t.x << "," << t.y << endl;

  return 0;
}

```

The result of running this is:

```
1,2
5,2

```

Type::x cannot be modified externally, so it is read-only, but via TypeFriend it can be changed. This can be useful if you wanted to expose a simple interface of direct member access for reading, but wanted to restrict how those members could be changed.