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.
Related
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 )
{
}
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)
}
};
Since I maked x as protected, shouldn't class B inherit x from A?
class A {
public:
A() {
}
protected:
int x = 0;
};
class B: public A{
B():x(1){
}
};
int main()
{
B b;
}
I'm getting that x does not exist on B
Inherited member variables cannot be set in the initializer list of the constructor. You can either initialize it after your brackets, or do something like this:
class A {
public:
A(int x) : x(x) {
}
protected:
int x = 0;
};
class B : public A {
public:
B() : A(1) {
}
};
int main()
{
B b;
return 0;
}
Since I maked x as protected, shouldn't class B inherit x from A?
Protected doesn't mean that the member is "inherited". A base is inherited, and the base contains all of its members (including the private ones). Protected access specifier means that the derived class has access to the name.
A base can only be initialised with a constructor of base. Members of a base cannot be initialised separately from it. Following would be correct:
struct B {
B(int x) : x(x) {}
protected:
int x = 0;
};
struct D : B{
D() : B(1) {}
};
Since I maked x as protected, shouldn't class B inherit x from A?
Yes, it does. You can use it inside B constructor or any B member functions, eg
B() { x = 2; } // ok
I'm getting that x does not exist on B
However, you can't initialise x in the initialisation list. So thing like this won't work:
B():x{1} // no
You can only initialise x it A constructor where it is a member variable.
casting shared pointer from B class to A class is not working the console output isn't 12 it's (it outputs A's x but i want B's x)(probably an other memory address). what's wrong with my code
#include <iostream>
#include <memory>
class A
{
public:
int x;
};
class B : public A
{
public:
B(){}
B(const B*){}
int x = 12;
};
std::shared_ptr<A> create()
{
return std::make_shared<B>(new B);
}
int main(){
std::shared_ptr<A> p;
p = create();
std::cout << p->x << std::endl;
std::cin.get();
return 0;
}
A::x and B::x are different objects. Variable access is never polymorphic in C++, so when you access p->x, you're accessing A::x. A::x was never initialized though, so the behavior of your program is undefined.
You need to either have your derived class's constructor initialize the base class's object or delegate that responsibility to the base class's constructor:
class A
{
public:
A(int x) : x{x} {}
int x;
};
class B : public A
{
public:
B() : A{12} {}
};
Live Demo
Alternatively you could wrap x in a virtual accessor method:
class A
{
public:
virtual ~A() = default;
virtual int x() const = 0;
};
class B
{
public:
int x() const override
{
return x_;
}
private:
int x_ = 12;
};
Live Demo
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
}