EDIT: None of the code is mine, it was all given to me and I’m just analyzing it from an object allocation methods point of view.
I’m having a really hard time with memory allocation. I promise you I’ve looked at a hundred examples on here over the last 5 hours. I understand this is probably poorly worded and I apologize in advance.
1.) I don’t understand why Version 2 prints class A’s f() instead of class B’s. The line
A* objA1 = objB;
is declaring a pointer, objA1, that points to an object of type A and it is assigning its address to where objB is pointing, B(2,3). I’ve read the sentence” if they’re heap-dynamic objects, then you can assign b1 to a1″. When I call objA1->f(), am I simply saying go to this location, oh you found a B? well cast it into an A and call f().
2.) I would have thought Version 1 sliced objB, because it is saying set this object which has been allocated room for A, equal to B which is larger. But if I put cout << objB.bf; after this assignment, it is still valid. is A objA1 = objB; not statically declaring objA1? And once again, why wouldn’t this print B’s f()?
3.) What is the difference between the two objA1 assignments? As in what functionality would only work with one of the two. Could you call both “heap-dynamic” if you wanted to give it an outdated classification of sorts?
class A {
private:
int a;
public:
A(int ia) {a = ia;}
void f() {
cout << "Call to method f defined in class A" << endl;
}
};
class B : public A {
private:
int b;
public:
B(int ia, int ib) : A(ia) {b = ib;}
void f() {
cout << "Call to method f specialized in class B" << endl;
}
void bf() {
cout << "Call to class B own method bf" << endl;
}
};
// C++ driver - Version 1
void main() {
A objA = A(1);
B objB = B(2,3);
objA.f();
objB.f();
objB.bf();
A objA1 = objB;
objA1.f();
}
// C++ driver - Version 2
void main() {
A* objA = new A(1);
B* objB = new B(2,3);
objA->f();
objB->f();
objB->bf();
A* objA1 = objB;
objA1->f();
}
C++ does not use dynamic dispatch by default. This means that calling
p->f()whenpis declared asX *pwill always callX::f(), regardless of the dynamic type of the instance pointed to byp. To enable dynamic dispatch, the function must be declaredvirtual. This is in contrast against Java/C#, where all member functions are implicitlyvirtual.The slicing in “Version 1” indeed occurs, however,
objBis in no way affected by being assigned somewhere. It’sobjAthat is affected by slicing (i.e. it ignores the part ofobjBwhich is not part ofA).