Derived class cannot access the protected member of the base class - c++

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.

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.

Call base class constructor after member constructor

I have the following class hierarchy, where the Base class depends on its derived class to supply it an argument in its constructor:
class Member
{
public:
Member(int v);
};
class Base
{
public:
Base(const Member& m);
};
class Derived : public Base
{
public:
Derived() : m_(123), Base(m_) // <- here is the problem
{
}
private:
Member m_;
};
The problem is, though, that in Derived's constructor, the Base constructor gets called first, when Derived's member variable m_ which it depends on isn't initialized yet.
Is there a way to force the compiler to call the constructor of m_ first or should I just rework my class hierarchy?
You can simulate initializing your member before the base class by making it it's own base class which you initialize first. You can wrap it in a simple class type and have Derived inherit privately from that type before Base. In the following example, Derived has a Member _m; which is initialized and then used to initialize Base.
class Member
{
public:
Member(int) {}
};
class Base
{
public:
Base(const Member&) {}
};
// The new wrapper
struct member_wrapper
{
member_wrapper(int v) : m_(v) {}
Member m_;
};
class Derived : private member_wrapper, public Base
{
public:
Derived() : member_wrapper(123), Base(m_)
{ }
};
Though in this case, since m_ is already a class type and Derived has no other members with that type, you can just inherit privately from Member directly. If you had a non-class type or multiple members of the same type that needed to be initialized before Base you would need to wrap them.
class Member
{
public:
Member(int) {}
};
class Base
{
public:
Base(const Member&) {}
};
class Derived : private Member, public Base
{
public:
Derived() : Member(123), Base(*this)
{ }
};

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

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

How to access member with same name in the inheritance

I have a question about how to access the member with the same name with inheritance. For example,
class Base {
public:
int i;
};
class Derived1 : public Base {
public:
int i;
// how to access the i in the base class here?
};
int main() {
Derived1 d;
cout<<d.i; //which is it is?
//how to access the different i here?
}
d.i in your example refers to the i in the derived class.
You can refer to the base class i by qualifying it with the base class name:
d.Base::i
In general, it's a bad idea to have derived classes with members having the same name as members in base classes.

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