Class Variables: Public Access Read-Only, But Private Access Read/Write

Class variables: public access read-only, but private access read/write

Of course you can:

class MyClass
{
int x_;

public:
int x() const { return x_; }
};

If you don't want to make a copy (for integers, there is no overhead), do the following:

class MyClass
{
std::vector<double> v_;

public:
decltype(v)& v() const { return v_; }
};

or with C++98:

class MyClass
{
std::vector<double> v_;

public:
const std::vector<double>& v() const { return v_; }
};

This does not make any copy. It returns a reference to const.

Class variable: public access read-only, but private access r/w

Write a public getter but no public setter. And the field itself private

making public member read only

class A{
private:
int a;
public:
const int &ref = a;
};

is there any thing wrong with this way if I have to provide a variable that is only read-only

There are at least a couple drawbacks with this design decision for class A.

1: Class Size

Also as Dieter Lücking mentions in a
comment:

increasing the size of the class, needlessly

2: Copy Semantics

It breaks the compiler generated copy assignment operator. For example, the following code behavior is generally desirable but doesn't work.

A obj1;

// ...

A obj2;

// make changes to 'obj2'

// Update 'obj1' with the changes from 'obj2'
obj1 = obj2; // This copy doesn't work!

More information:

  • Should I prefer pointers or references in member data?
  • Assignment operator with reference class member
  • Thinking in C++, 2nd ed. Volume 1 ©2000 by Bruce Eckel, 11: References & the Copy-Constructor

There are certain rules when using references:

  1. A reference must be initialized when it is created. (Pointers can be initialized at any time.)
  2. Once a reference is initialized to an object, it cannot be changed to refer to another object. (Pointers can be pointed to another object at any time.)
  3. You cannot have NULL references. You must always be able to assume that a reference is connected to a legitimate piece of storage.

It may be possible to implement a custom assignment operator but that's more code to maintain (i.e., another drawback in my opinion).

#include <iostream>

class A
{
private:
int a;

public:
explicit A(int value) : a(value) {}

A& operator=(const A& other)
{
a = other.a;
return *this;
}

const int& ref = a;
};

int main()
{
A obj1(10);
std::cout << "1: " << obj1.ref << "\n";

A obj2(20);
std::cout << "2: " << obj2.ref << "\n";

obj1 = obj2;
std::cout << "1: " << obj1.ref << "\n";

return 0;
}

The idiomatic way to address this issue is to use a proper accessor function.

class A {
private:
int a;

public:
int getA() const { return a; }
};

Link public and private variables (with write access to private variables)

Not sure if it's a good design pattern since inline getters are fast but you could create constant references to your private variables:

class test_vec
{
private:
int x, y;
int data[2];
public:
const int &x_ext, &y_ext;
int data_ext[2];

// you have to initialize the references before constructor body
// references cannot be let uninitialized
test_vec(int x, int y) : x_ext(this->x), y_ext(this->y)
{
this->x = x;
this->y = y;

}

~test_vec()
{}

inline void set_x(int x)
{
this->x = x;
}

inline void set_y(int y)
{
this->y = y;
}
};

when x or y changes x_ext and y_ext follow:

Hello World
test has the properties (1, 2)
test has the properties (4, 10)

Bonus: constant references cannot be modified. That's the closest thing of a read property that you got here :)

If you don't want that restriction, just remove the const qualifier, but since you're encouraging encapsuation now that you have C++ I would let it as is and let the writers hit the wall on that (not to mention a good sed/regex replacement could refactor all your writes automatically)

C++ - How to make read only class member variables in Visual Studio 2010

Change this:

template <class T, class C>
class proxy {
friend class C;

to this:

template <class T, class C>
class proxy {
friend C;

Because C is a template parameter, it's not guaranteed that C will necessarily be a class type.

Read-only member variable of class

Your optimisation is useless and will result in the exact same code. All of readonly is trivial and will be inlined, eliminating any overhead it might have over using raw T. So, the solution is to not fix a problem that doesn't exist, and just use readonly<int, A> regardless of whether this is debug build or not.

As @MooingDuck noted, you should change your constructor to use init list (and probably make it explicit, too).

C# public variable as writeable inside the class but readonly outside the class

Don't use a field - use a property:

class Foo
{
public string Bar { get; private set; }
}

In this example Foo.Bar is readable everywhere and writable only by members of Foo itself.

As a side note, this example is using a C# feature introduced in version 3 called automatically implemented properties. This is syntactical sugar that the compiler will transform into a regular property that has a private backing field like this:

class Foo
{
[CompilerGenerated]
private string <Bar>k__BackingField;

public string Bar
{
[CompilerGenerated]
get
{
return this.<Bar>k__BackingField;
}
[CompilerGenerated]
private set
{
this.<Bar>k__BackingField = value;
}
}
}


Related Topics



Leave a reply



Submit