Reputation:
class A{
private:
int a;
public:
const int &ref = a;
};
int main() {
A obj;
obj.a = 20; // error cause private
obj.ref = 30; // not private but const so ERROR
return 0;
}
I'm trying to make a member variable accessible but read only through the interface. Currently I've tried this approach and it seems to compile fine. I made a const reference
to my original variable int a
and made it public
. Is there anything that's wrong with this practice that I might be missing out? Or is this example safe and sound to use for practical purposes?
Nothing wrong with providing a member function with const
correctness applied (and I've used that too and intend to do so always), but I'm asking is there any thing wrong with this way if I have to provide a variable that is only read-only.
Thankyou :)
Upvotes: 0
Views: 2429
Reputation: 9602
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
.
Also as Dieter Lücking mentions in a comment:
increasing the size of the class, needlessly
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:
There are certain rules when using references:
- A reference must be initialized when it is created. (Pointers can be initialized at any time.)
- 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.)
- 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; }
};
Upvotes: 3
Reputation: 1427
The standard way to do this in C++ is by making the actual member private
but including a public 'getter' method for the interface, as below:
class A{
private:
int a;
public:
int get_a() const { return a; }
A() : a(20) {}
};
int main() {
A obj;
int n = obj.get_a(); // n = 20
return 0;
}
The user cannot set the value of A::a
but can use A::get_a
to retrieve its value.
Upvotes: 3