1

in C++ is it a bad practice to use reference in place of getters?

for example:

class X { int mP; public: const int& P; X():P(mP){} }; 

and later

X xl; int h = xl.P; 
6
  • The above code is extremely dangerous, as you lack a copy constructor, and the copy constructor you get by default does not do what you want done. :) Commented Nov 14, 2013 at 20:10
  • 1
    Why not make mP public? Commented Nov 14, 2013 at 20:12
  • The whole point of getters/setters is that the object knows when data changes; its a level of abstraction. If you are trying to get around this, do what @juanchopanza says. Commented Nov 14, 2013 at 20:13
  • I do not have any requirement like this but, I was just wondering if this can do any harm. @Yakk will a copy constructor come into picture while initializing a reference?? Commented Nov 14, 2013 at 20:20
  • @user2173884 If you interested in such questions, then you are ready to pick theese classic books: Effective C++ series by Scott Meyers and Exceptional C++ series by Herb Sutter. The Definitive C++ Book Guide and List Commented Nov 14, 2013 at 20:42

2 Answers 2

1

Just think about refactoring to make the access thread safe, that won't work well this way and require a lot of changes in the client classes/functions.

If you have class members, that are guaranteed not to be changed over lifetime of the instance, you can simply provide const int P; and initialize it properly in your class' constructors.

If the value is to be visible class wide use a static const int P;

In any other case use a public getter:

int P() const; // a return type of 'const int &' would be redundant 

1st shot implementation:

int X::P() const { return mP; } 

Thread safe implementation:

class X { { // ... private: // ... mutable std::mutex internalDataGuard; }; int X::P() const { std::lock(internalDataGuard); return mP; } 
Sign up to request clarification or add additional context in comments.

1 Comment

@user2173884 Depend's on your use case. But if you abstract it out in your designs early (as you don't do with public const int& P;), will make it easier to scale out later. I think I have explained the exceptional cases well.
0

None of this is good:

class X { public: int x; }; class X { private: int m_x; public: const int& get() const { return m_x; } public: void set(const int& other) { m_x = other; } }; class X { private: int m_x; public: const int& x() const { return m_x; } public: void x(const int& other) { m_x = other; } }; class X { private: int m_x; public: const int& x() const { return m_x; } public: int& x() { return m_x; } }; 

Pick one, it's a design decision.

Having 'const int& x' to publish the private member will work:

class X { private: int m_x; public: const int& x; public: X() : m_x(0), x(m_x) {} // Take care for copy and assignment }; 

The cost is a larger memory footprint.

5 Comments

How would this cost larger memory footprint?
@user2173884 the class stores x plus the reference to x
I guess Reference do not take any memory. they are resolved during compile time, they are just an alias in variable table created by compiler which does not exist after linking.
@user2173884 Nope - they take the same space as a pointer does.
Indeed. I just checked it actually take pointer size. Valid point to not to use this.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.