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.
Related
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.
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.
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();
}
// inheritence experiment
#include"stdafx.h"
#include<iostream>
using namespace std;
class base
{
private:
int i;
};
class derived: public base
{
private:
int j;
};
int main()
{
cout << endl << sizeof(derived) << endl << sizeof(base);
derived o1;
base o2;
cout << endl << sizeof(o1) << endl << sizeof(o2);
}
I'm getting this output:
8
4
8
4
why's that so? private data members of a base class aren't inherited into the derived class, so why I am getting 8 bytes for both, the size of derived and o1 ?
Private members are inherited. You just cannot access them from your derived class.
The private members are actually in the derived class, they're just not accessible within the derived class. The private keyword is to prevent programmers that derive from the base class from changing values the designer of the base class didn't want you to change because it might alter the functionality of the base class.
Have a look here for a deeper explanation
Fragile base class
class base {
public:
base(int v) : m_value(v) { }
int value() { return m_value; }
private:
int m_value;
};
class derived : private base {
derived(int v) : base(v) { }
int value2() { return value(); }
};
int main()
{
derived d(2);
return d.value2();
}
How do you expect this to work if the private base class doesn't store the value somewhere?
Your choice of words "inherited into the derived class" makes me think you are confused about how inheritance works. Members from the base class are not inherited into or copied into the derived class. The derived class contains an instance of the base type, as a sub-object within the complete derived object, so a derived class is (usually) at least as large as the sum of its base classes.
Consider this code:
struct A {
private:
int i;
};
struct B {
int j;
};
struct derived : A, B {
int k;
};
An A object is laid out in memory as an int, and so is a B.
A derived object could be laid out in memory as an A object, followed by a B object, followed by an int, which means it is a sequence of three ints. Whether the base class members are public or private doesn't affect that.
Of course they are inherited -after all, the behavior of the base-class will probably depend on them being there-, they are just not accessible!
Inherited methods of the base class can still use the private memebers. They have to be there.
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;
};