Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 862753
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 15, 20262026-05-15T09:11:44+00:00 2026-05-15T09:11:44+00:00

Consider the sample application below. It demonstrates what I would call a flawed class

  • 0

Consider the sample application below. It demonstrates what I would call a flawed class design.

#include <iostream>

using namespace std;

struct B
{
 B() : m_value(1) {}

 long m_value;
};

struct A
{
 const B& GetB() const { return m_B; }

 void Foo(const B &b)
 {
  // assert(this != &b);
  m_B.m_value += b.m_value;
  m_B.m_value += b.m_value;
 }

protected:
 B m_B;
};

int main(int argc, char* argv[])
{
 A a;

 cout << "Original value: " << a.GetB().m_value << endl;

 cout << "Expected value: 3" << endl;
 a.Foo(a.GetB());

 cout << "Actual value: " << a.GetB().m_value << endl;

 return 0;
}

Output:
Original value: 1
Expected value: 3
Actual value: 4

Obviously, the programmer is fooled by the constness of b. By mistake b points to this, which yields the undesired behavior.

My question: What const-rules should you follow when designing getters/setters?

My suggestion: Never return a reference to a member variable if it can be set by reference through a member function. Hence, either return by value or pass parameters by value. (Modern compilers will optimize away the extra copy anyway.)

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-15T09:11:45+00:00Added an answer on May 15, 2026 at 9:11 am

    Obviously, the programmer is fooled by the constness of b

    As someone once said, You keep using that word. I do not think it means what you think it means.

    Const means that you cannot change the value. It does not mean that the value cannot change.

    If the programmer is fooled by the fact that some other code else can change something that they cannot, they need a better grounding in aliasing.

    If the programmer is fooled by the fact that the token ‘const’ sounds a bit like ‘constant’ but means ‘read only’, they need a better grounding in the semantics of the programming language they are using.

    So if you have a getter which returns a const reference, then it is an alias for an object you don’t have the permission to change. That says nothing about whether its value is immutable.


    Ultimately, this comes down to a lack of encapsulation, and not applying the Law of Demeter. In general, don’t mutate the state of other objects. Send them a message to ask them to perform an operation, which may (depending on their own implementation details) mutate their state.

    If you make B.m_value private, then you can’t write the Foo you have. You either make Foo into:

    void Foo(const B &b)
    {
        m_B.increment_by(b);
        m_B.increment_by(b);
    }
    
    void B::increment_by (const B& b)
    {
        // assert ( this != &b ) if you like 
        m_value += b.m_value;
    }
    

    or, if you want to ensure that the value is constant, use a temporary

    void Foo(B b)
    {
        m_B.increment_by(b);
        m_B.increment_by(b);
    }
    

    Now, incrementing a value by itself may or may not be reasonable, and is easily tested for within B::increment_by. You could also test whether &m_b==&b in A::Foo, though once you have a couple of levels of objects and objects with references to other objects rather than values (so &a1.b.c == &a2.b.c does not imply that &a1.b==&a2.b or &a1==&a2), then you really have to just be aware that any operation is potentially aliased.

    Aliasing means that incrementing by an expression twice is not the same as incrementing by the value of the expression the first time you evaluated it; there’s no real way around it, and in most systems the cost of copying the data isn’t worth the risk of avoiding the alias.

    Passing in arguments which have the least structure also works well. If Foo() took a long rather than an object which it has to get a long from, then it would not suffer aliasing, and you wouldn’t need to write a different Foo() to increment m_b by the value of a C.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 470k
  • Answers 470k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer A lot of cryptographic proofs rely on very general mathematical… May 16, 2026 at 3:09 am
  • Editorial Team
    Editorial Team added an answer To be able to send email you need an outgoing… May 16, 2026 at 3:09 am
  • Editorial Team
    Editorial Team added an answer It's only possible if you're inlining user-controlled variables in a… May 16, 2026 at 3:09 am

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.