Reputation: 14438
I am really getting confused in following examples:
#include <iostream>
class C {
public:
int a,b;
};
int main() {
C c{3,6};
std::cout<<c.a<<'\n';
std::cout<<c.b<<'\n';
return 0;
}
It works fine and gives the expected outcome. But if I modify the above code like below.
#include <iostream>
class C {
int a,b;
public:
int get_a(){
return a;
}
int get_b(){
return b;
}
};
int main(){
C c{3,6};
std::cout<<c.get_a()<<'\n';
std::cout<<c.get_b()<<'\n';
return 0;
}
In the above program compiler shows multiple errors. Why uniform initialization allowed in first program but not in second? Where I am wrong?
Upvotes: 0
Views: 93
Reputation: 15924
By default c++ class
members are private
, so without specifying you get a private variable. Because you made the types private you do not get the aggregate-initialization for free anymore so you need to write your own constructor for this class:
class C{
C(int _a, int _b):
a(_a), b(_b)
{}
};
You just need to fix the namespacing for the cout
and your code should compile fine: http://coliru.stacked-crooked.com/a/1d69f4f141d2bcd2
From the standard:
[dcl.init.aggr] An aggregate is an array or a class with no user-provided constructors, no brace-or-equal-initializers for non-static data members, no private or protected non-static data members, no base classes, and no virtual functions
In the first code you only had public variables so the code worked because you had an aggregate, making the variable private is what caused the problem because it was no longer an aggregate according to the above definition.
Upvotes: 3
Reputation: 4023
The first code worked because the data members a
and b
were public, so they could be accessed from outside the class. However, in the second code, they are declared as private, so they cannot be accessed from outside the class. Either declare them as public again, or use a constructor as follows (if you still want them as private):
C(int x,int y) // This is a parameterised constructor
{
a=x;
b=y;
}
And initialise them as C c(3,6);
Upvotes: 1
Reputation: 311088
In the modified version of the code, you moved the public:
label so the a
and b
data members are no longer public. Hence, they cannot be referenced from outside the class, even not implicitly by an initializer list.
Upvotes: 1
Reputation: 8986
You need to move the line int a,b;
into the public:
scope like the first example.
You also need std::
in front of cout
#include <iostream>
class C {
public:
int a,b; //Make public
int get_a(){
return a;
}
int get_b(){
return b;
}
};
int main(){
C c{3,6};
std::cout<<c.get_a()<<'\n'; //use namespace std::
std::cout<<c.get_b()<<'\n'; //use namespace std::
return 0;
}
Upvotes: 1
Reputation: 180424
a
and b
are private
in your second example and are therefore inaccessible from outside the class.
Upvotes: 1