-6

I have two questions

1) Why can we give default value if the member is public but when it is private we are not allowed? Take below example:

#include <iostream>
using namespace std;
class Test
{
private:
    int a=5;
public:
    Test()
    {
        cout<<a<<endl;
        cout<<"default const";
        a=0;
    }

};
int main()
{
    Test x;
    cout<<x.a;

}

We get below error for this:

Compile Errors :
prog.cpp: In function 'int main()':
prog.cpp:6:11: error: 'int Test::a' is private
     int a=5;
           ^
prog.cpp:19:13: error: within this context

Whereas if I make it public as below:

#include <iostream>
using namespace std;
class Test
{ 
public:
    int a=5;
    Test()
    {
        cout<<a<<endl;
        cout<<"default const";
        a=0;
     }

};
int main()
{
    Test x;
    cout<<x.a;

}

We get output as :

5
default const0

2) My next question is, why do we have this behavior? Also when we provide this default value, why constructor value overrides the default value provided in class?

  • 6
    The error you see is not in the class constructor and has nothing to do with default values. The error happens in the expression `cout << x.a`. And it demonstrates the entire purpose of `public`/`private` access control. – Kerrek SB Sep 10 '18 at 08:53
  • Because you're trying to access it from main, the compiler is just telling you which variable declaration is the problem (it just happens to include initialisation). – George Sep 10 '18 at 08:53
  • 2
    A meta comment: This question isn't about "different behaviour": since one of the two examples is ill-formed, it isn't valid C++ and doesn't "behave" at all. "Different behaviour" usually means that two things both compile and run, but produce different observable effects given the same inputs. – Kerrek SB Sep 10 '18 at 08:55
  • 1
    Possible duplicate of [What are public, private and protected in object oriented programming?](https://stackoverflow.com/questions/1020749/what-are-public-private-and-protected-in-object-oriented-programming) – Sander De Dycker Sep 10 '18 at 08:59
  • I don't think that's the actual, complete, error message from your compiler. – molbdnilo Sep 10 '18 at 09:20

4 Answers4

3
  1. The member is private, you get the error where you're trying to print it, outside of the class.

  2. Simple enough, first all of the default values are assigned (constructed, see comment), then the code inside the constructor is executed. That's why you see the 5 inside the constructor.

If you want the constructor to change the initialization value of a, you can use an initializer list:

Test(): a{0}
{
    cout<<a<<endl;
    cout<<"default const";
}

And this would print 0, the value of a will never be 5 when using this constructor.

N00byEdge
  • 1,106
  • 7
  • 18
  • 2
    "default values are assigned" - nope, default values are not assigned (default values are constructed). You can see it here http://coliru.stacked-crooked.com/a/26f3951020f96db3 It is small technicality, but i think it is worth to be mentioned. – Andrew Kashpur Sep 10 '18 at 09:13
  • Yeah, you're right. I edited my answer. I just wanted to keep the answer simple, but I suppose it should be as accurate as possible :P – N00byEdge Sep 10 '18 at 14:48
1

We can assign the value to the private member variables as well but it seems that you are accessing private member variable a outside of class which is not allowed.

Mayur
  • 2,583
  • 16
  • 28
1

The error message is a little misleading; the problem is with your usage. The declaration has been shown to you for context, and because the declaration happens to include an initialiser it looks like the error is about that initialisation. But it isn't.

So, we don't have that behaviour.

As for why assigning a value to the member "overrides" your initialised value, well, that's what assigning does. When you initialise something it gets a value, then when you assign to it later, now it has that value instead. It's the same as a simple local variable:

int x = 42;
x = 3;

What value does x hold now?

The code in the constructor's body is "later". By the time it fires, all member initialisations (be they default, or with values you've provided) have already completed.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
0

To (2), and specifically the "why": in-class initializers act as a default that are not dependant on any input passed to constructors, whereas constructor initializers can be seen as a specialization. Imagine a class with 10 contructors, all require the same static value for x, you should stick to in-class initializers to avoid redundant code.

dan
  • 303
  • 1
  • 3