Inheritance Access Issue - c++

Am geting the following error, "Use of deleted function 'Derived::Derived'" while executing the below code related to Inheritance. Also in the note it says, "Derived::Derived() is implicitly deleted because
the default definition would be ill informed". Can someone help me in fixing this:
#include <iostream>
//BASE CLASS
class Base
{
public:
int a;
void display()
{
std::cout << "a = " << a << ", b = " << b << ", c = " << c << std::endl;
}
//constructor
Base(int la, int lb, int lc) : a {la}, b {lb}, c {lc}
{
}
protected:
int b;
private:
int c;
};
//DERIVED CLASS
class Derived : public Base
{
//a from Base is Public
//b from Base is Protected
//c from Base has No access
public:
void access_base_members()
{
a = 100; //OK since a is Public in parent
b = 200; //OK since b is Protected type in Parent. So derived CLASS will have access
//c = 300; //NOK since c is private in parent and hence cannot be accessed
}
};
int main()
{
std::cout << "\nBase Member access=>\n\n";
Base base(1,2,3);
base.a = 10; //OK
//base.b = 20; //NOK since Protected
//base.c = 30; //NOK since Private
base.display();
Derived derived;
derived.a = 111; //OK since public in parent
//derived.b = 222; //NOK since protected members cannot have direct access in OBJECTS
//derived.c = 333; //NOK since private
}

The base class does not have the implicit default constructor because there is explicitly declared constructor
Base(int la, int lb, int lc) : a {la}, b {lb}, c {lc}
{
}
So the default constructor of the derived class that by default has to call the default constructor of the base class is defined as deleted.
Thus the compiler issues an error message for this declaration
Derived derived;
You need explicitly to define a constructor for the derived class.
For example you could define it like
Derived() : Base( 0, 0, 0 )
{
}
Or/and
Derived(int la, int lb, int lc ) : Base( la, lb, lc )
{
}

Related

Same hierarchy, different behaviour when accessing protected member of base class

I came across this code in a past exam:
#include <iostream>
class cls1
{
protected:
int x;
public:
cls1()
{
x = 13;
}
};
class cls2 : public cls1
{
int y;
public:
cls2()
{
y = 15;
}
int f(cls2 ob)
{
return (ob.x + ob.y);
}
};
int main()
{
cls2 ob;
std::cout << ob.f(ob);
return 0;
}
This works just fine and outputs 28. The problem is, it seems to contradict with this code (found in another exam):
#include <iostream>
class B
{
protected:
int x;
public:
B(int i = 28)
{
x = i;
}
virtual B f(B ob)
{
return x + ob.x + 1;
}
void afisare()
{
std::cout << x;
}
};
class D : public B
{
public:
D(int i = -32)
: B(i)
{
}
B f(B ob)
{
return x + ob.x - 1;/// int B::x is protected within this context
}
};
int main()
{
B *p1 = new D, *p2 = new B, *p3 = new B(p1->f(*p2));
p3->afisare();
return 0;
}
It's the same type of hierarchy, but one has access to ob.x and the other one doesn't. Can someone explain to me why that is?
The difference is, in the 1st case the protected member is accessed through the derived class. In the 2nd case the protected member is accessed through the base class, which is not allowed.
For protected members,
(emphasis mine)
A protected member of a class is only accessible
2) 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:
struct Base {
protected:
int i;
private:
void g(Base& b, struct Derived& d);
};
struct Derived : Base {
void f(Base& b, Derived& d) { // member function of a derived class
++d.i; // OK: the type of d is Derived
++i; // OK: the type of the implied '*this' is Derived
// ++b.i; // error: can't access a protected member through
// Base (otherwise it would be possible to change
// other derived classes, like a hypothetical
// Derived2, base implementation)
}
};

C++ how to access value of inherited and overridden attribute of base class?

I try to do something like this:
class A{
public:
A(){number = 1;}
int number;
};
class B : public A{
public:
B(){number = 2;}
};
class Base {
public:
Base() {myAttribute = new A();}
int returnAttrNumber(){return myAttribute->number;}
A *myAttribute;
};
class Inherited : public Base{
public:
Inherited(){myAttribute = new B();}
B *myAttribute;
};
int main()
{
Inherited *i = new Inherited();
std::cout << i->returnAttrNumber(); // outputs 1, because it gets the A not the B. I want it to output 2, to get the B object in returnAttrNumber()
}
So, class Base holds an object A. Inherited holds an A-derived object B. And I try to call a method on the base class, but I want it to cast down in the hirarchy of the corresponding Object as far as possible (without static_cast or dynamic_cast) and then take the B object, not A and do stuff (returning it's number in in this case)
Is there a way to do that downcasting from a base class in C++ without big difficulties?
Thanks for answers!
This is very bad design. The quick answer is you can access variable from the base class via the fully qualified identifier. Take the following example:
#include <iostream>
class A
{
public:
A()
: var(1) {}
protected:
int var;
};
class B : public A
{
public:
B()
: var(2) {}
int getBVar() const
{
return var;
}
int getAVar() const
{
return A::var;
}
private:
int var;
};
int main()
{
B b;
std::cout << "A: " << b.getAVar() << std::endl;
std::cout << "B: " << b.getBVar() << std::endl;
}
Which outputs the following:
A: 1
B: 2
About the down casting bit... Base and Inherited have different variables. You can not safely case one to the other.
Well as rioki said,
Base and Inherited have different variables
This is because I redeclared MyAttribute as a B in Inherited. This was the mistake. I thought, when I declare it with the same name, it will be the same variable, that's wrong.
So the whole solution for this is to uncomment this one line in Inherited. Working code:
class A{
public:
A(){number = 1;}
int number;
};
class B : public A{
public:
B(){number = 2;}
};
class Base {
public:
Base() {myAttribute = new A();}
int returnAttrNumber(){return myAttribute->number;}
A *myAttribute;
};
class Inherited : public Base{
public:
Inherited(){myAttribute = new B();}
//B *myAttribute;
};
int main()
{
Base *i = new Inherited(); // this works, what is necessary in my case
std::cout << i->returnAttrNumber(); // outputs 2 now
}

C++ linking base class members to derived class members

class B_mem {
public:
int b_var;
};
class D_mem : public B_mem {
public:
int d_var;
};
class B {
public:
B_mem b_member;
};
class D : public B {
public:
D_mem d_member;
};
int main () {
D derived;
D_mem dmem;
dmem.b_var = 2;
dmem.d_var = 3;
B* b_ptr = &derived;
std::cout << b_ptr->b_member.b_var; // Doesn't print 2
}
How can I structure the classes such that when I set/update D_mem, it automatically sets/updates B_mem (if relevant)? In the example above, I create D and fill D_mem but then access D with a pointer of type B. I want to be able to access the base class members of D_mem in D through B_mem.
I am wondering if there is something with polymorphism, copy constructors, or set functions that will allow me to do this without having to manually keep D_mem and B_mem in agreement.
std::cout << b_ptr->b_member.b_var; // Doesn't print 2
Of course it doesn't.
The lines
D_mem dmem;
dmem.b_var = 2;
dmem.d_var = 3;
did nothing to change the member variable of derived. They are still in an uninitialized state.
You can use:
int main () {
D derived;
D_mem& dmem = derived.d_member; // Get a reference to an existing object
dmem.b_var = 2; // Modify the referenced object
dmem.d_var = 3;
// That still doesn't change b_member.
// Need to update it too.
derived.b_member.b_var = 2;
B* b_ptr = &derived;
std::cout << b_ptr->b_member.b_var; // Doesn't print 2
}
or
int main () {
D derived;
D_mem dmem;
dmem.b_var = 2;
dmem.d_var = 3;
derived.d_member = dmem; // Set the value of derived.
derived.b_member = dmem;
B* b_ptr = &derived;
std::cout << b_ptr->b_member.b_var; // Doesn't print 2
}
Re:
I am wondering if there is something with polymorphism, copy constructors, or set functions that will allow me to do this without having to manually keep D_mem and B_mem in agreement.
You can do that if you provide member functions that take care of those details and make the member variables private but it gets messy since you have essentially two instances of B_mem in D.
The code becomes simpler and easier to maintain if you use a pointer instead of objects.
Here's a sample implementation:
#include <iostream>
#include <memory>
class B_mem {
public:
int b_var;
virtual ~B_mem() {}
};
class D_mem : public B_mem {
public:
int d_var;
};
class B {
protected:
std::shared_ptr<B_mem> b_member;
public:
B(std::shared_ptr<B_mem> member) : b_member(member){}
virtual ~B() {}
virtual B_mem& getMember() = 0;
virtual B_mem const& getMember() const = 0;
};
class D : public B {
public:
D() : B(std::shared_ptr<B_mem>(new D_mem)){}
D_mem& getMember()
{
return *(std::dynamic_pointer_cast<D_mem>(b_member));
}
D_mem const& getMember() const
{
return *(std::dynamic_pointer_cast<D_mem>(b_member));
}
};
int main () {
D derived;
derived.getMember().b_var = 2;
derived.getMember().d_var = 3;
B* b_ptr = &derived;
std::cout << b_ptr->getMember().b_var << std::endl;
}
Output:
2

How does an inherited member function in C++ work with children member variable?

For instance, I have base class A:
class A {
public:
callA() {
val = 100;
std::cout << this->val << std::endl;
}
int val;
}
class B : public A {
public:
B() {
val = 10;
}
int val;
}
B b;
b.callA();
What will b.callA() print?
And for B inheriting A, if B does not have a field val, will B share an exact reference to A's val, or is it a copy?
Internally, any instance of Class B contains an entire copy of Class A. In fact, when you initialize a new instance of Class B, Class A's constructor is run first. Therefore, when you call a non-virtual function from the base class, it will run as if it were run from the base class, which is internal to the derived class. It can even access the private variables of the base class (which the derived class wouldn't be able to access, it only has access to public/protected variables from the base class).
Example:
#include <iostream>
using namespace std;
class A
{
public:
A()
{
cout << "Base constructor!" << endl;
privateVar = 10;
}
void testPrint()
{
cout << "privateVar: " << privateVar << endl;
}
private:
int privateVar;
};
class B : public A
{
public:
B()
{
cout << "Derived Constructor!" << endl;
}
};
int main()
{
B testB;
testB.testPrint();
return 0;
}

Class templates and casting

So I'm trying to write a copy constructor for class E such that it will get every int x from each class and assign it to its counterpart. How do I cast the right side?
class A
{
public:
int x;
};
class B: public virtual A
{
public:
int x;
};
class C: public virtual A
{
public:
int x;
};
class D : public B, public C
{
public:
int x;
};
class E: public D
{
public:
int x;
E(const E& e)
{
E::x = (E)e.x // problem
D::x = ?
C::x = ?
B::x = ?
A::x = ?
}
};
You do not need to cast an int to assign it to an int. Just do:
self->x = ((E)e).x;
D::x = ((D)e).x;
E::x = e.E::x;
D::x = e.D::x;
C::x = e.C::x;
B::x = e.B::x;
A::x = e.A::x;
Though it might be wiser to give each class a suitable copy constructor, with a suitable initialization list invoking copy constructors of base classes.