Can objects of derived classes in C++ be accessible by parent class? - c++

The rules state that an in the case of a public specifier - object of derived class can be treated as object of base class (not vice-versa). What does that mean?
Can all public elements (in any class) be accessible by anything/anywhere?
Does this refer to the fact that for the parent class attributes and methods defined as public are accessible by the derived class. But in the case that the attributes and methods from the derived class are public they aren't accessible by the parent/base class?
In a public base class
Base class members How inherited base class members appear in derived class
private: x ------------------------> x is inaccessible
protected: y ------------------------> protected: y
public: z ------------------------> public: z
but what about in reverse?

I suppose the correct question would be "Can members (not objects) of derived classes in C++ be accessible by parent class?"
Public and protected members (data members and functions) of the base class are accessible to the derived class.
Public members of a class are accessible from anywhere. Of course, they need to be accessed through an instance of that class.
But in the case that the attributes and methods from the derived class are public theyaren't accessible by the parent/base class?
They can be if you have an instance of the derived class. You can then access the public members of the derived class from the base class.
Edit:
Example where base class member accesses public member of derived class and vice versa.
class Base
{
public:
void funcBase();
};
class Derived : public Base
{
public:
void funcDerived();
};
void
Base::funcBase()
{
Derived d;
d.funcDerived();
}
void
Derived::funcDerived()
{
Base b;
b.funcBase();
}
int main()
{
Base b;
Derived d;
b.funcBase();
d.funcDerived();
}

It means if you have Bar that is a derived class of Foo.
class Foo
class Bar : public Foo
So you can say, as expected
Foo* myFoo = new Foo;
Bar* myBar = new Bar;
You can also make a Foo from a Bar since a Bar is a type of Foo
Foo* myOtherFoo = new Bar;
You cannot make a Bar from a Foo, that is what "object of derived class can be treated as object of base class (not vice-versa)" means.
Bar* myOtherBar = new Foo;

You asked:
Can objects of derived classes in C++ be accessible by parent class?
Yes. See below for a pattern that I have seen a few times.
You also asked:
Can all public elements (in any class) be accessible by anything/anywhere?
Yes, of course.
Example pattern of base class accessing derived class members
Entity.h:
class Attribute;
class Entity
{
public:
Entity(Attribute* att);
void save(FILE* fp);
void print();
private:
Attribute* att_;
};
Attribute.h:
#include "Entity.h"
class Attribute : public Entity
{
public:
void save(FILE* fp);
void print();
};
Entity.cc:
#include "Entity.h"
#include "Attribute.h" // Needed to access Attribute member functions
Entity::Entity(Attribute* att) : att_(att) {}
void Entity::save(FILE* fp)
{
// Save its own data.
//...
// Save the Attribute
att_->save(fp);
}
void Entity::print()
{
// Print its own data to stdout.
//...
// Print the Attribute
att_->print();
}

Related

C++: Why Protected Constructor Cannot be Accessed in the Derived Class?

Protected member is supposed to be accessible from derived class.
Then, why I got the compiling error in the code below?
class A {
protected:
A() {};
};
class B : public A {
public:
void g() {
A a; // <--- compiling error: "Protected function A::A() is not accessible ...". Why?
}
};
int main() {
B b;
b.g();
}
I noticed there is a related post, but the class there is a template class. Mine is just a "regular" class.
Why the derived class cannot access protected base class members?
protected members could be accessed from derived class, but only when through the derived class.
A protected member of a class is only accessible
...
to the members and friends (until C++17) of any derived class of that class, but only when the class of the object through which the protected member is accessed is that derived class or a derived class of that derived class:
So you can't create an indpendent object of base class even in member functions of derived class.
Put it in another way, the protected members of the current instance of derived class could be accessed, but protected members of independent base class can't. E.g.
class A {
protected:
int x;
public:
A() : x(0) {}
};
class B : public A {
public:
void g() {
this->x = 42; // fine. access protected member through derived class
A a;
a.x = 42; // error. access protected member through base class
}
};
Protected member is supposed to be accessible from derived class.
Yes, but only when accessed via the this pointer. Not when accessed on a complety separate object. Which you are trying to do, when B::g() tries to construct a new A object.

accessing data member through composition

I have a struct obj in my base class. I don't know how to access the data members of the struct through Derv1 class (Derived from the base class). I tried making both Base and Derv1 a friend of struct - it still tells me ' data member is private' (its private in Base only).
example :
struct A{
public :
int total;
//some stuff
};
class MyClass{ // [Base] class
private:
A var1;
};
class Derv1{
private:
//some stuff
public void display_var1(Derv1 x){
return x.var1.total;
} // trying to return the value of A.total
};
I hope this makes sense so that you can help me out ..
Thank You kindly,
First, you have to make sure that Derv derives from MyClass.
class Derv1 : public MyClass { ... };
and then, you will need to figure out the best way to display the variable.
My suggestion:
Create a virtual member function in the base class.
Override the function in the derived class.
Make sure to call the base class implementation in the derived class implementatin.
class MyClass { // [Base] class
public:
virtual void display() const
{
// Display var1 anyway you wish to.
}
private:
A var1;
};
class Derv1 : public MyClass {
public:
virtual void display() const
{
// Call the base class implementation first
MyClass::display():
// Display anything else that corresponds to this class
}
private:
//some stuff
};
i think you must extend your Derv1 class into the Base class:
class Derv1: public MyClass{
to inherit the members of the base class

Derived class cannot access the protected member of the base class

Consider the following example
class base
{
protected :
int x = 5;
int(base::*g);
};
class derived :public base
{
void declare_value();
derived();
};
void derived:: declare_value()
{
g = &base::x;
}
derived::derived()
:base()
{}
As per knowledge only friends and derived classes of the base class can access the protected members of the base class but in the above example I get the following error "Error C2248 'base::x': cannot access protected member declared in class " but when I add the following line
friend class derived;
declaring it as friend , I can access the members of the base class , did I do some basic mistake in the declaring the derived class ?
The derived class could access the protected members of base class only through the context of the derived class. On the other word, the derived class can't access protected members through the base class.
When a pointer to a protected member is formed, it must use a derived
class in its declaration:
struct Base {
protected:
int i;
};
struct Derived : Base {
void f()
{
// int Base::* ptr = &Base::i; // error: must name using Derived
int Base::* ptr = &Derived::i; // okay
}
};
You can change
g = &base::x;
to
g = &derived::x;
My compiler actually said I needed to add a non-default constructor to base because the field is not initialized.
After I added
base() : g(&base::x) {}
it did compile without problems.

A confusion about c++ inheritance

when using inheritance, I read from a tutorial that says
Conversely, if the most restricting access level is specified (private), all the base class members are inherited as private and thus cannot be accessed from the derived class.
So I test following code but the derived class can still access the member of base class.
Why?
#include <iostream>
using namespace std;
class Polygon {
protected:
int width, height;
public:
Polygon():width(10),height(10){}
};
class Rectangle: private Polygon {
public:
int area ()
{ return height; }
};
int main () {
Rectangle rect;
cout << rect.area() << '\n';
return 0;
}
output is 10
The derived type can access public and protected members of the base class. This is independent of the type of inheritance. But the members are all private in the derived type if the inheritance is private.
class Foo
{
public:
int i;
};
class Bar : private Foo
{
public:
void hello() {
++i; // OK, I can see Foo's public and protected members
}
};
int main()
{
Bar b;
b.hello(); // accesses i internally. OK
b.i; // Error, i is private in Bar
}
Private inheritance means that all the base members become private to the derived class. The derived class itself can still access the members, but no further derived classes can.
According to the C++ Standard
If a class is declared to be a base class for another class using the
private access specifier, the public and protected members of the
base class are accessible as private members of the derived class117.
So in your example protected data members of the base class
protected:
int width, height;
are accessible as private members of the derived class and any member function of the derived class can access its private dara members.

How do you make a private member in the base class become a public member in the child class?

Consider the following code:
class Base
{
void f() { }
};
class Derived: public Base
{
public:
};
What can you change in the derived class, such that you can perform the following:
Derived d;
d.f();
If the member is declared as public in the base class, adding a using declaration for Base::f in the derived class public section would've fix the problem. But if it is declared as private in the base class, this doesn't seem to work.
This is not possible. A using declaration can't name a private base class member. Not even if there are other overloaded functions with the same name that aren't private.
The only way could be to make the derived class a friend:
class Derived;
class Base
{
void f() { }
friend class Derived;
};
class Derived: public Base
{
public:
using Base::f;
};
Since you make the names public in the derived class anyway so derived classes of Derived will be able to access them, you could make them protected in the base-class too and omit the friend declaration.
You cannot access a private member from the derived class. What you can do is make it protected, and use a using declaration:
class Base
{
protected:
void f() { }
};
class Derived: public Base
{
public:
using Base::f;
};