Reputation: 612
I have this code, note that two lines have been commented out
#include <iostream>
class foo {
public:
foo();
int i;
};
class bar: foo {
public:
bar();
//int i;
};
foo::foo()
{
i = 2;
}
bar::bar()
{
i = 4;
}
int main()
{
bar *b = new(bar);
//std::cout << "bi = " << b->i << std::endl; /*line 28*/
foo *f = (foo*) b;
std::cout << "fi = " << f->i << std::endl;
}
With the two lines commented out, the code compiles and the output is
fi = 4
With the two lines uncommented, the code compiles and the output is
bi = 4
fi = 2
With only the declaration of i within class bar commented out the compilation fails
var.cc: In function ‘int main()’:
var.cc:6:7: error: ‘int foo::i’ is inaccessible
var.cc:28:30: error: within this context
I understand the first two cases but I do not understand this compilation error. Why is
the variable "i" accessible from within the bar constructor but not from a bar pointer?
Upvotes: 1
Views: 95
Reputation: 8994
You should directly specify name scope of fields, if they has same name in different classes:
struct s1
{
int i;
};
struct s2 : public s1
{
int i;
};
int main()
{
s2 v;
v.s1::i = 1;
v.s2::i = 2;
std::cout << v.s1::i << v.s2::i << std::endl;
return 0;
}
Output will be 12
Upvotes: 0
Reputation: 5116
The reason for this is that you are using private inheritance.
For all class
es, private
is the default access modifier. This means that members and bases are private
unless otherwise stated.
For a struct
however, the default is public
. Indeed, this is the only difference between a class
and a struct
.
Hence, when writing class bar: foo
, this is equivalent to class bar: private foo
.
To get rid of the issue, you need to do either class bar: public foo
or struct bar: foo
, both of which are equivalent in your example (since you have no members using the default access modifier).
Upvotes: 1
Reputation: 206526
In private inheritance all members of base class become private
members of the derived class. Note that for classes the default inheritance is private
when you do not specify any.
Since i
acts as an private
member of bar
, it can be accessed in bar::bar()
but not from outside the member functions.
Good Read:
What are access specifiers? Should I inherit with private, protected or public?
Upvotes: 3