12

I'm stuck with a c++ problem. I have a base class that has a self referential object pointer inside the private visibility region of the class. I have a constructor in the base class that initializes these two pointers. Now I have my derived class whose access specifier is private(I want to make the public member functions of my base class private). Now through the member functions of my derived class I want to create an object pointer which can point to the private data of the base class, that is ,those self referential object pointers. My code is:

class base{
private:
     base *ptr1;
     int data;
public:
     base(){}
     base(int d) { data=d }
};

class derived:private base{
public:
     void member()
};

void derived::member()
{
base *temp=new base(val); //val is some integer
temp->ptr1=NULL; //I can't make this happen. To do this I had to declare all the
                 //private members of the base class public. 
}
rehctawrats
  • 221
  • 5
  • 16
Rahul Chitta
  • 303
  • 1
  • 2
  • 11
  • 11
    Use `protected` rather than `private` ? – Paul R Sep 22 '13 at 13:45
  • 4
    Make a `protected` getter for the `private` member? Usually your design is flawed if you need such solutions, though. – Marc Claesen Sep 22 '13 at 13:48
  • That doesn't work either. Compiler error. Tried that as well. Only by making it public I can access it. But that would make the code vulnerable. – Rahul Chitta Sep 22 '13 at 13:49
  • 3
    `protected` is what you need (this is what `protected` is for). If you get an error there are other issues. Post a [SSCCE](http://www.sscce.org/) and the error if you want people to better understand your problem. – LorenzoDonati4Ukraine-OnStrike Sep 22 '13 at 13:53
  • 2
    The very question is, unfortunately, flawed. You may think you want, or need, to do that; but you do not. And not only is it not necessary, it is also harmful. A `class` uses `private` attributes for **encapsulation**; encapsulation in turn means that the class can maintain **invariants** about its attributes and the exact representation of the state is **hidden** to avoid accidental dependencies. Break encapsulation, and you open a nasty can of worms. – Matthieu M. Sep 22 '13 at 15:04
  • Thanks for answering to that. I just wanted to look at all the possibilities and explore in every way. – Rahul Chitta Sep 22 '13 at 15:12

5 Answers5

19

Derived class can not access the private members of it's base class. No type of inheritance allows access to private members.

However if you use friend declaration you can do that.

Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
  • I know that but isn't there any way to do it. The only other option is to use friend classes. But I want to solve the problem using inheritance. – Rahul Chitta Sep 22 '13 at 13:44
  • You can access the private member directly by its memory address. It doesn't really involve inheritance but it works. – Edward Severinsen Apr 20 '18 at 03:54
13

There is no other way to access other class's private data then friendship. What you can do with inheritance, however, is to access protected data of the base class. But it doesn't mean you can access protected data of another object of the base type. You can only access protected data of the base part of the derived class:

class base{
protected:  //protected instead of private
     base *ptr1;
     int data;
public:
     base(){}
     base(int d) { data=d; }
};

class derived:private base{
public:
     void member();
};

void derived::member()
{
    base *temp=new base(3); 
    //temp->ptr1 = 0; //you need friendship to access ptr1 in temp

    this->ptr1 = 0; // but you can access base::ptr1 while it is protected
}

int main(){}
cpp
  • 3,743
  • 3
  • 24
  • 38
2

try to give protected as the access specifier in base class and inherit the base class in private mode.....but for further using member functions of base class u may need few short inline functions as they will also be converted to private

1

Well I think, you were trying to achieve a result like this!! This does not report any compiler error or such. Good luck!!!

class base{
private:
     base *ptr1;
     int data;
public:
     base(){}
     base(int d) { data=d; }
     base* getPtr();   //getter to get access to base pointer
     void setPtr(base* val); // setter to set value of the pointer variable
};

base* base::getPtr()
{
    return ptr1;
}

void base::setPtr(base* val)
{
    ptr1 = val;
}

class derived:private base{
private:
    base* getPtr();
    void setPtr(base* val);
public:
     void member();

};

base* derived::getPtr()
{
    return base::getPtr(); //derived version just invokes the base class version

}

void derived::setPtr(base* val)
{
    base::setPtr(val);     //derived version just invokes the base class version

}
void derived::member()
{
    base *temp=new base(5); //put in a random number here instead of val
    temp -> setPtr(nullptr);
}
Parag
  • 55
  • 6
-3

I disagree with some of the other answers claiming the only way to access the private member is by making it a friend.

You can directly access the private member via its address in memory. If you're comfortable with it that is. You could have a function in the base class that returns the address of the private member and then use some wrapping function in the derived class to retrieve, dereference and set the private member.

  • 1
    Is my answer being down voted because it doesn't work? Because as far as I know you can access a private member variable via its address in memory. There is no access violation for a non member function accessing a private member of another class. This is a solution, although one some might not prefer, it does work. – Edward Severinsen May 30 '18 at 05:45
  • 1
    Your answer got downvoted because, even if it works, it goes against all the basic principles of object oriented programming. Private, protected and public exist for a reason, and circumventing them can make the code non portable, brittle, hard to comprehend, ... – Pietro Jan 28 '21 at 11:29
  • 4
    @Pietro I was still in high school when I made this answer. I've learned a lot since then. I get it now, thanks for the explanation though. – Edward Severinsen Mar 06 '21 at 21:21
  • 1
    your answer is absolutely valid, C++ is not an object-oriented language, no matter how hard people want to make it look like one. the fact of the matter is, C++ inherits pointer arithmetic from C, so if it's possible - it's a valid option. C++ has a notion of what is "right" and "wrong", accessing private members directly is "wrong". I tend to agree with that because any logic you'd need to overcome this would make the architecture more complex. I'd rather make the base class a simple C-struct with public fields and avoid complexity. especially if it's inside a module. – Absolute Virtue Aug 16 '22 at 13:00
  • I once showed someone in a job interview how I had "fixed" an incorrect use of `private` in the Microsoft Application Wizard by clobbering the virtual table. (The wizard template generated base and derived in the wrong order: flat out MS bug.) I also told the interviewer if a junior programmer brought me that solution I would consider firing them. The problem is there was no requirement that the vtable pointer was 4 bytes before the official memory address of the object. That's common, but you could put it at the end… – Andrew Lazarus Nov 30 '22 at 08:58