Richard Johnson
Richard Johnson

Reputation: 612

member variable inheritance

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

Answers (3)

Dmitry Sazonov
Dmitry Sazonov

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

Agentlien
Agentlien

Reputation: 5116

The reason for this is that you are using private inheritance.

For all classes, 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

Alok Save
Alok Save

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

Related Questions