0
class Foo {
private:
    string x;
};

class Bar : public Foo {
public:
    void get_data() {
        cin >> x;
    }
};

I don't quite understand why this line of code is not working. Isn't the ability to do this the purpose of inheriting member variables?

JobHunter69
  • 1,706
  • 5
  • 25
  • 49

2 Answers2

4

This is not possible. private means the variable's name is only accessible by exactly that class (and any friends).

The access specifier protected means accessible by that class, derived classes, and friends. You could either make x be protected, or move get_data() into public section of Foo.

M.M
  • 138,810
  • 21
  • 208
  • 365
  • Isn't the string inherited for Bar? – JobHunter69 Nov 03 '16 at 02:08
  • @Goldname Yes but the name is inherited as *no access*, so you cannot use the name `x` to access it. – M.M Nov 03 '16 at 02:08
  • Then what's the purpose of it being inherited? – JobHunter69 Nov 03 '16 at 02:09
  • 1
    @Goldname Inheritance represents an "is-a" relationship . A `Bar` is a `Foo` with extras. So all of `Foo` is inherited. – M.M Nov 03 '16 at 02:10
  • Yes but I cannot access or set any of Foo's attributes in Bar, so what would be the use? – JobHunter69 Nov 03 '16 at 02:11
  • @Goldname: That's a question you need to ask yourself. You designed the class, after all. It's perfectly valid to have encapsulation against derived classes accessing certain members. It may not be reasonable for your use case, so if it isn't, then change your design. – Nicol Bolas Nov 03 '16 at 02:12
  • @Goldname Sorry I don't understand the question beyond what I have already answered. As Nicol Bolas said, if you want to use `x` in `Bar` then make it `protected`. That's what `protected` is for. `private` is for when you do not want `Bar` to be able to change `x` (via its name) – M.M Nov 03 '16 at 02:12
  • Once inherited, an instance of Bar will have an "x" of its own. I do not understand why "x" cannot be accessed by Bar. In other words, exactly like you said, a Bar is a Foo with extras, so why can a Foo access "x" but Bar cannot? – JobHunter69 Nov 03 '16 at 02:31
  • I can see why a derived class does not want some base class members or member functions. In this case, the purpose of it being inherited seems to me like a waste of memory since it cannot be used. – JobHunter69 Nov 03 '16 at 02:32
  • @Goldname: `Bar` derives from `Foo`, so a `Bar` object can be used wherever a `Foo` is expected. All of `Foo`'s data members contribute to `Bar`'s total size in memory. But by declaring `x` as `private`, `Foo` is declaring that all descendants, including `Bar`, cannot access `x` even though `x` physically resides in their memory. `Foo` does not want descendants messing around with `x` directly. – Remy Lebeau Nov 03 '16 at 02:32
  • @RemyLebeau and isn't that a waste of memory? – JobHunter69 Nov 03 '16 at 02:33
  • @Goldname Let's say you're making a `Thread` class. Do you want child classes to be able to get their hands into the private members? Maybe you do. If you do, then now when you want to refactor stuff, you're breaking existing code, and people complain at you. If you don't refactor stuff, people use your code in a way it was never meant to be used, and they complain when it breaks. On the other hand, if you can expose only what you want exposed, then you can keep people from getting into the nitty-gritty through compile-time blocks, which keeps people safe from themselves -- including you. – Nic Nov 03 '16 at 02:34
  • @Goldname Again, "*`Bar` derives from `Foo`, so a `Bar` object can be used **wherever a `Foo` is expected***". That means `Bar` has to contain all of `Foo`'s members in order for `Bar` to act as a valid `Foo` object. Here is another example: `Animal` has a private member `legs`. `Human` and `Dog` derive from `Animal`. Any kind of Animal has to know how many legs it has, but any given sub-species of Animal cannot change the number of legs it has. So `legs` is private to `Animal`, but still exists in `Human` and `Dog`. – Remy Lebeau Nov 03 '16 at 02:34
  • @Goldname Bar instances can access the private Foo members through the (public or protected) Foo methods. But Bar methods cannot directly use the private Foo members. – n.caillou Nov 03 '16 at 02:34
  • @RemyLebeau So, how are the number of legs for Human and Dog set? – JobHunter69 Nov 03 '16 at 02:44
  • @Goldname: it could be a parameter passed to the `Animal` constructor, for instance. Once an Animal has `legs` set, there would be no need to change it later (except maybe for amputations, which could be a public method of the `Animal` class). `Animal` could declare `legs` as `private` to prevent different legs from magically (dis)appearing out of thin air behind `Animal`'s back. It would need to be due to some external action (ie public method) that `Animal` is aware of. Just because something is `private` doesn't mean it is not important, it just means it is protected from unintended use. – Remy Lebeau Nov 03 '16 at 02:51
  • @RemyLebeau Shouldn't the Human or Dog constructor be used to set this number? – JobHunter69 Nov 03 '16 at 03:03
  • @Goldname their constructors could and should pass the value to `Animal`'s constructor. – Remy Lebeau Nov 03 '16 at 03:58
0

private are hidden from subclasses. only friends (and Foo itself) can access it. Perhaps you want x to be protected?

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
  • Well, I thought that all member variables including private ones were inherited.http://stackoverflow.com/questions/14270631/c-do-sub-classes-really-inherit-private-member-variables – JobHunter69 Nov 03 '16 at 02:07
  • 1
    @Goldname sure they are there, but they can't be accessed. – Daniel A. White Nov 03 '16 at 02:08
  • @Goldname Private members are inherited in the sense that they are present in the derived objets' memory representation. But you're not allowed to use them in your code (i.e. the base class developpers have no intention of maintaining backwards compatibility for what's private). – n.caillou Nov 03 '16 at 02:31