How to make a derived class access the private member data? - c++

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.
}

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.

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(){}

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

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);
}

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.

Related

DerivedA pointer pointing to DerivedB

I have a base class which serves as an interface (if I use that word correctly). The idea is that the base class has some derived classes that implement one virtual function of the base class. Then I also need another class that extends the base class (lets call it extended base). What I would like is that I can store a class derived from base into an extended base pointer.
MWE:
class Base {
public:
virtual ~Base();
virtual double value();
}
class Derived : public Base{
public:
double value() override {return 5;}
}
class ExtendedBase : public Base {
public:
virtual ~ExtendedBase ();
virtual double value2(){return 10;}
}
int main() {
ExtendedBase * object;
object = new Derived();
std::cout << object->value(); //should give implementation in Derived, i.e. 5
std::cout << object->value2(); //should give implementation in ExtendedBase, i.e. 10
delete object;
return 0;
}
With this MWE I get a compile error at the second line in the main. error: cannot convert 'Derived*' to 'ExtendedBase*' in assignment object = new Derived();. Part of me understands why it doesn't work (although I can't explain), but I would like to know if I can get the desired behaviour in some other way.
P.S. Sorry about the bad question name, I couldn't think of another way to keep it short
P.S.2 I know raw pointers like this are not advised. In the future I will change to smart pointers but I don't think they are needed for this simple example
ExtendedBase and Derived are each derived from Base. If you want to use an ExtendedBase* pointer to point to a Derived object, you will need to derive Derived from ExtendedBase.
To use a different example,
class Feline{
virtual void run();
}
class Housecat : Feline{
void run() {}
}
class BigCat : Feline{
virtual void run();
virtual void roar();
}
Here Feline, Housecat, and BigCat are analogous to Base, Derived, and ExtendedBase. BigCat and Housecat are each Feline, but since Housecat is not a BigCat, you can't use a BigCat* pointer to point to a Housecat.
This is the desired behavior from a language architect perspective.
For instance, if you have
class Ship
{
public:
virtual void move() = 0;
}
class Steamboat : public Ship
{
public:
virtual void move() override { ... }
}
class Sailboat : public Ship
{
public:
virtual void move() override { ... }
virtual void setSails() { ... }
}
Now, you don't want a Steamboat to become a Sailboat all of a sudden, hence:
Steamboat* tootoo = new Sailboat;
cannot be valid.
That's why your code cannot work. Conceptually.
So giving a quick fix is not possible, because your concept is not really clear.
When you are assigning an address to a pointer that means you should be able to access all the members of the type the pointer is pointing to through the pointer.
For ex,
class B {};
class D : B {};
B *p = new D();
now through p, at least you can access all the members of base portion of the derived class.
But in your code,
ExtendedBase * object;
object = new Derived();
object should be able to access all the members of ExtendedBase portion of the derived class. But how is it possible as derived class is not derived from ExtendeBase. So compiler is throwing error.
You need to do some changes in your code to work.
To make base as interface (abstract class), you need to define at
least one member function as pure virtual.
If you want to access the member function of ExtendedBase through
Base pointer, you should define same function 'val' in your
ExtendedBase.
Below are the changes.
#include <iostream>
using namespace std;
class Base {
public:
virtual ~Base() {};
virtual double value() = 0;
};
class Derived : public Base{
public:
~Derived() {};
double value() {
return 5;
}
};
class ExtendedBase : public Base {
public:
virtual ~ExtendedBase () {};
double value()
{
return 10;
}
};
int main() {
Base *p = new Derived();
std::cout << p->value() << std::endl;
delete p;
Base *p1 = new ExtendedBase();
std::cout << p1->value() << std::endl;
delete p1;
return 0;
}

What is the whole idea of virtual function?

Here in the code i am able to successfully point a derived class pointer to a base class object and I m also able to set and get value of the base class private member. If this is not giving any issues then what is the need of virtual functions and the whole confusion around run time polymorphism/late binding/vtable bla bla bal!!!
#include <iostream>
using namespace std;
class Base
{
int a;
public:
Base(int x=0):a(x){}
void setValueForMember(int p)
{
a=p;
}
void showValueOfMember(){cout<<endl<<a<<endl;}
};
class Derived:public Base
{
int b;
public:
Derived(){}
Derived(int y):b(y){}
void setValueForMember(int q)
{
b=q;
}
void showValueOfMember(){cout<<endl<<b<<endl;}
};
int main()
{
Derived D;
D.setValueForMember(10);
Derived *Dptr = new Derived();
Dptr = &D;
Dptr->showValueOfMember();
Base B;
Dptr = (Derived*)&B;
Dptr->setValueForMember(20);
Dptr->showValueOfMember();
return 0;
}
Virtual function is used in the case when , we want to access the members of the derived class using the pointer of type, base class.
when you will use
Bptr=&D;
you won't be able to access the members of Derived class , except the members inherited from the Base class.
If you want to access the members of the Derived class using the same pointer that is Bptr, you must have to use virtual function,
and at the time of compilation it is decided that which function is going to be executed, that's why it is known as
Run-Time polymorphism or Dynamic Binding
.

Access private data type in base class if only private function exist

Given the code below, we can access private data of base class if the function in base are protected by using inheritance. My question is, is there any way we can access private data if all methods in base class are also set to private?
class Base
{
int i;
protected:
void set(int data){
i = data;
}
int get(){
return i;
}
};
class derive: Base{
public:
void change(int x){
set(x);
cout<<get()<<endl;
}
};
int main()
{
derive b;
b.change(3);
return 0;
}
"we can access private data of base class if the function in base are protected by using inheritance", no you're not really accessing private data. You're invoking a setter in the base class that does it for you. And no you won't be able to call the private methods of your base class.
Setting the members to private in the base class will make it private for all children as well. You can define new public functions to change these members in the children.
By using friend
Making the derive class the friend of Base
class derive;//forward declaration
class Base
{
int i;
private:
void set(int data){
i = data;
}
protected:
int get(){
return i;
}
public:
friend class derive;
};
class derive : public Base{
public:
void change(int x){
set(x);
cout<<get()<<endl;
}
};
You should be aware of public/protected inheritance. class a : public/protected b
Do not use access specifier overloading/overriding:
C++: overriding public\private inheritance
http://www.learncpp.com/cpp-tutorial/116-adding-changing-and-hiding-members-in-a-derived-class/
Now I show how to redeclare the access specifier of an inherited member:
class derive : public Base{
public:
Base::set;//this is valid redeclaration within public scope. Now anybody could use derive::set(x)
void change(int x){
set(x);
cout<<get()<<endl;
}
}

Private inheritance usage from client

I had a question related to private inheritance in C++.
My question is based on a reference related to this page here.
(Under the heading "But What If We Do Need To Inherit?")
The case is point is I declare a base class with a public virtual function. Then I inherit base class under private inheritance and name it derived class. this is shown as below
class base {
public:
base() {}
virtual ~base() {}
virtual void func_1() {
cout<<"base func1"<<endl;
}
void func_t() {
cout<<"base funct"<<endl;
func_3();
}
private:
void func_3() {
cout<<"base func3"<<endl;
func_1();
}
};
class derived: private base {
public:
derived() {}
~derived() {}
virtual void func_1() {
cout<<"derived func1"<<endl;
}
};
base* b = new derived;
b->func_t();
The above statements give error that base is an inaccessible base of derived.
What do I do if I want to call the func_1 as part of above function call function of the derived?
private indicates that names and members are not accessible from outside. The conversation to a private base class is one occourrence. You can simply wrap this conversation into a member function to let it work:
class derived
: private base {
public:
// other stuff
base* get_base() {
return this;
}
};
derived* d = new derived;
base* b = d->get_base();
b->func_t();
Since you inherit base as a private base class, this means that all public members of base (including base::func_1) will be private in derived. The compiler will complain when you declare derived::func_1 as public.
If you need derived::func_1 as public, then you should inherit base publicly. If you do not need it to be public, then you should declare derived::func_1 as being private.

How to make a member readonly for derived classes?

Given an abstract base class with a protected member, how can I provide read access only to derived classes?
To illustrate my intention I provide a minimal example. This is the base class.
class Base
{
public:
virtual ~Base() = 0;
void Foo()
{
Readonly = 42;
}
protected:
int Readonly; // insert the magic here
};
This is the derived class.
class Derived : public Base
{
void Function()
{
cout << Readonly << endl; // this should work
Readonly = 43; // but this should fail
}
};
Unfortunately I cannot use a const member since it have to be modifiable by the base class. How can I produce the intended behavior?
The usual way to do it is to make your member private in the base class, and provide a protected accessor:
class Base
{
public:
virtual ~Base() = 0;
void Foo()
{
m_Readonly = 42;
}
protected:
int Readonly() const { return m_Readonly; }
private:
int m_Readonly;
};
As protected member is visible in derived class, if you want the member to be readonly in derived class, you can make it private, and provide a getter function.
class Base {
public:
Base();
virtual Base();
public:
int getValue() {return value;}
private:
int value;
}
This way you can still change the value in base class, and it's readonly in children class.
Best-practice guidelines for inheritance should be to always make member variables private and accessor functions public. If you have public functions that you only want called from derived classes it means you are writing spaghetti code. (source: Meyer's Effective C++ item 22)