I have a doubt regarding some concept of inheritance, i am stating what i know, please correct me if i am wrong.
Private members of base class are inherited by the derived class but derived class can't access them by any means.
Protected members of base class are inherited by the derived class but derived class can't access it directly, but by the help of some of its member functions.
Now in the following code:
class A
{
protected:
A(const A&){}
A operator=(const A &){}
int t;
public:
A(int r) {t=r;}
A(){t=0;}
};
class B : public A
{
A a;
public:
void make(void)
{
//A b(a); //LINE 1 -------COPY CONSTRUCTOR BEING CALLED ---protected member of base class
cout<<t; //LINE 2 -------protected member of base class
}
};
int main()
{
B b;
b.make();
return 0;
}
Why there is error for LINE 1 coming??
Why we can't call copy-constructor for object of A?
Many many thanx in advance
A protected member can only be accessed by other members of the same complete object, during construction, destruction, or via the this pointer(*).
In your example class hierarchy, a B object has two subobjects of type A:
The base class subobject, which it gets by deriving from A, and
The data member subobject named a, which it gets by declaring a.
A member of B may only access protected members from the first A subobject, not from the second, because only the first directly uses the this pointer (note that your expression cout << t is semantically equivalent to cout << this->t).
Access to the members of the data member do not directly use the this pointer: if you tried to access this->a.t from B::make, the this pointer is not used directly to access the t. In your declaration A b(a);, the copy constructor is called not for this, but for the new A object you are constructing, the local variable named b.
(*) Or, of course, by any member in the class that declares it: any member function of B can call any other member function of B
Related
class a
{
public:
int var;
};
class b : a
{
};
int main()
{
a* p = new b();
return 0;
}
I know its caused by private inheritance but i wanna know why is it so?
This is just what "private" means in private inheritance. The fact that b inherits from a is an implementation detail and not visible from outside.
I'm not trying to access any private member outside the class, or any protected one outside class hierarchy, I'm just trying to create a dynamic object with a base class pointer and it raises an error
You are trying to access a conversion from a b* to a a* but you cannot, because from outside, the base class is not accessible. Private inheritance is closer to composition rather than public inheritance. Your example could be rewritten as
class b {
a a_instance;
};
The implementation of b will be slightly different (because call to a member functions is via a_instance instead of this), but the effect is the same: We compose b of a and users have no knowledge of that (aka private).
You explicitly specified that the base class is inherited as a private sub-object of the derived class. So it is inaccessible outside the class definition.
From the C++ 17 Standard(14.2 Accessibility of base classes and base class members)
...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
class.
In this declaration
a* p = new b();
there is an attempt to access the private sub-object of the type a of an object of the type b because the static type of the pointer p is a *.
In fact this statement
a* p = new b();
has the same semantic as for example
class A
{
private:
int x = 10;
};
A a;
int *p = &a.x;
If this was allowed then using a pointer you could change a private subobject of an object.
Lets say I have a base class with protected member:
class Base
{
public:
Base(int data)
: m_attribute(data) {}
protected:
int m_attribute;
};
and derived class from base:
class Derived : public Base
{
public:
int get_attribute()
{
return m_attribute;
}
};
First of all: I can do this, right? Is this totally legal?
If yes, then here is the question:
I can't change anything in a Base class;
I have a Base class object, and I need to access its m_attribute member;
Should I do downcasting from this base class object to derived class object first, and then call get_attribute() function? Something like this:
Base base(5);
Derived* derived = static_cast < Derived*>(&base);
int base_attribute = derived->get_attribute();
Or what are other ways to access protected member? I know that friend function is an option, but I can't change anything in the base class
Should I do downcasting from this base class object to derived class object first, and then call get_attribute() function?
Most definitely not. An instance of a base class is not an instance of a derived class. Your conversion is ill-formed.
Here is a valid way:
struct kludge : Base {
kludge(const Base& b): Base(b) {}
operator int() {
return m_attribute;
}
};
usage:
Base base(5);
int foo = kludge(base);
This kludge works by copy constructing the base sub object of the derived type. This of course depends on the base being copyable - which your Base is. It's easy to tweak to work with movable as well.
As a syntactic sugar, the kludge is implicitly convertible to the type of the member. If you prefer, you could use a getter.
if base class doesn't have a default constructor after overloading it to take some arguments and no default one is there then the derived classes must use member-initializer list to initialize the base part otherwise you cannot instantiate the derived class getting the compiler complaining about missing default constructor in base class:
class Base
{
public:
// Base(){} default constructor by default the compiler creates one for you unless you overload it so the next one taking one parameter will hide this one
Base(int data) // hides the default ctor so derived classes must use member-initializer list
: m_attribute(data) {}
protected:
int m_attribute;
};
class Derived : public Base
{
public:
Derived() : Base(0){} // you must use member intializer list to initialize the part Base
//Derived(int x) : Base(x){} // also ok
int get_attribute(){ return m_attribute; }
};
int main()
{
Derived dervObj;
Derived* derived = static_cast < Derived*>(&baseObj);
int base_attribute = derived->get_attribute();
cout << base_attribute << endl;
}
also you cannot cast the address of class base to derived object but cast an object of base class to derived one.
so in your example writing in main:
Derived* derived = static_cast < Derived*>(&baseObj); // is like writing:
char* cp = static_cast < char*>(&int); // you must convert a variable not a type
why you want to access protected members from outside??? keep in mind that public inheritance will copy all the members of base to derived class but private.
using friendship or making member data public will make it possible to access it from outside but it undermines the principles of data-hiding and encapsulation however friendship in some cases it's a must and there's no other alternative then use it carefully but making data public it's better to get back to structs
The Derived class can access and modify the public and protected Base class properties and methods.
Then, you can't case Base into Derived.
Derived inherit from Base, so Derived is a Base.
But a Base is not a Derived (a Car is a Vehicle, a Vehicle is not a Car).
So if you need a getter, put it directly into Base, or instanciate a Derived instead of a Base.
Firstly:
Derived* derived = static_cast < Base*>(base);
This is not valid and illegal. Won't compile. You can't static cast Base to Base*.
And to answer your question:
Base base(5);
Derived& derived = static_cast<Derived&>(base);
std::cout << derived.get_attribute();
Or if you want to use a pointer because you think you're cooler:
Base base(5);
Derived* derived = static_cast<Derived*>(&base);
std::cout << derived->get_attribute();
EDIT: static_cast doesn't have any overhead on runtime. It is static, hence it's a compile-time thing. Both methods will yield the same result.
class base{
private:
int a;
public:
int b;
void setData(){
a = 10; b = 5;
}
};
class derived: public base{
private:
int c;
public:
// b is inherited
};
void main(){
derived D1;
D1.setData();
}
I learned that private members aren't inherited. So, the private variable a (in the base class) is not present in the derived class object. My question is when D1.setData() is called, how can it assign a value to a, if a doesn't exist?
I'm pretty sure I have this concept wrong, so can some one explain how this works? Are the base class members also created when the derived class object is created?
I learned that private members aren't inherited.
Of course they are inherited: otherwise, all member functions of the base class that need these private variables would be broken. Although private members are not accessible to the inheriting class, the base class retain full access to them.
Can some one explain how this works?
Layout of the inheriting class derived includes a place to store a, the private member of the base class. All methods of the base class can access base::a. At the same time, it remains inaccessible to the derived class: any attempt to access a from derived would cause a compile-time error.
Private member variables are inherited, but cannot be accessed externally. The memory pattern of inheritance is simple:
class base {
int x;
};
class subclassCpp : public base {
int y;
};
class subclassCStyle {
base a;
int y;
};
Now, subclassCpp and subclassCStyle have the exact same memory pattern, regardless of private/protected status, etc. This should illustrate how the memory is laid out.
For the other question, "Are the base class members also created when the derived class object is created?"
The answer is yes, a constructor is always invoked on the base class. If you don't add this yourself, the default constructor is automatically invoked. If the base class doesn't have a default constructor, it won't let you create a subclass constructor that doesn't properly invoke whatever constructor is necessary to initialize the base. So there is no legal way you can end up with a base class that hasn't been initialized when the subclass was created, as long as a constructor in the subclass was executed.
I have abstract class A, from which I inherit a number of classes. In the derived classes I am trying to access protected function in A trough A pointer. But I get a compiler error.
class A
{
protected:
virtual void f()=0;
};
class D : public A
{
public:
D(A* aa) :mAPtr(aa){}
void g();
protected:
virtual void f();
private:
A* mAPtr; // ptr shows to some derived class instance
};
void D::f(){ }
void D::g()
{
mAPtr->f();
}
The compiler error says : cannot access protected member A::f declared in class A.
If I declare mAPtr to be D*, instead A* everything compiles. And I don't understand why is this.
Relying on private access works on unrelated instances of the same type.
Relying on protected access works on unrelated instances of the same type (and of more derived types).
However, relying on protected access does not work on unrelated instances of a base type.
[n3290: 11.5/1]: When a friend or a member function of a derived
class references a protected nonstatic member function or protected
nonstatic data member of a base class, an access check applies in
addition to those described earlier in clause 11. Except when forming
a pointer to member (5.3.1), the access must be through a pointer
to, reference to, or object of the derived class itself (or any class
derived from that class) (5.2.5). If the access is to form a pointer
to member, the nested-name-specifier shall name the derived class (or
any class derived from that class).
So D or something derived from D, but not A.
It's an oft-questioned cute oddity about C++ that nonetheless is designed to try to avoid pitfalls. After all, you don't know what type *mAPtr really has.
A class containing a protected section means that this class allows derived classes to manipulate their base class in any way they choose (as far as the protected interface allows).
Class D objects can manipulate their own A part. In doing say they probably want to maintain some invariants.
Suppose there is (or will be in the future!) another class E, also inherited from A. Class E objects also can manipulate their own A part, and they may be enforcing different invariants.
Now, if a class D object was allowed to manipulate the A part of any object, it can't ensure the invariants. A D object may do something to the A part of an E object that breaks that E object. That's why it is not allowed.
But if you really want to, perhaps a way to call A::f, without exposing it to everybody, would be via a friend function.
class A;
namespace detail
{
void call_f(A*);
}
class A
{
friend void detail::call_f(A*);
private:
virtual void f() = 0;
};
namespace detail
{
void call_f(A* a) { a->f(); }
}
class D: public A
{
public:
void g() { detail::call_f(mAPtr); }
private:
void f() {}
A* mAPtr;
};
This relies on users being disciplined enough to stay out of namespaces whose name clearly indicates that it contains implementation details.
You forgot using ; after class declaration:
class A
{
protected:
virtual void f()=0;
};
class D : public A
{
public:
void g();
protected:
void f();
private:
A* mAPtr; // ptr shows to some derived class instance
};
Besides, you don't need to store base class pointer.
#include<iostream>
using namespace std;
class Base {
private:
int b;
public:
Base(int bvalue=0) {
b = bvalue;
cout << "B's ctor" << endl;
}
~Base() { }
};
class Derv : public Base {
public:
int d;
Derv(int bval, int dval) : Base(bval),d(dval) {
cout << "D's ctor" << endl;
}
Derv(int dval) : d(dval) {
cout << "D's ctor " << endl;
}
};
int main(){
Derv D1(4,5);
Derv D2(100);
return 0;
}
The above program compiles fine and I see the output as
B's ctor
D's ctor
B's ctor
D's ctor
Since private members of Base class are not inherited, what is the memory location the Base constructor is creating the private member in?
NB: This question contains a misconception which is fully addressed in the answers.
Private members are inherited; they are just not visible from the member functions in the subclass. So in an instance of Derv, b and d will likely be adjacent to each other in memory (although the compiler may choose to place the variables differently). Member functions in Derv cannot see b, but if you call a function that is inherited from Base, that function will be able to see b.
I'm not sure what you're trying to ask, but whenever a derived class's constructor is called it calls its parent class's constructor first. Note that a private variable is only private to access from methods outside of a class (and its friends). Regardless of how the Base class's constructor was called, it will have access to its own private member variable b. In other words, Derv cannot access b directly, but it can call the Base constructor to modify b for it.
Furthermore, as Tomalak points out, every Derived object contains a fully-constructed Base object, private members and all. If Base was derived from another class—CommonBase, let's say—every Derived object would also contain a fully-constructed CommonBase object, as well.
In the interests of being thorough, note that unless you explicitly specify otherwise, derived classes will also implicitly call the default constructor of their parent class.
Does that make sense?