0

I have some difficulties using this, it seems to slice my derived class. This example will help me to explain my problem.

class A 
{
    A() {
        OtherClass(*this);
    }

    virtual doSomething() = 0;
}

class B : public A
{
    B() : A() {}

    doSomething() override {
        std::cout << "Hi!" << std::endl;
    }
}

class OtherClass() 
{
    OtherClass(A &a) {
        a.doSomething();
    }
}

After some investigation it seems like that using *this slice the class B. And then OtherClass will call a pure virtual method on A. I'm wrong? Should I make the OtherClass(*this), after the Initialization of the B class?

Nitixx
  • 48
  • 6

2 Answers2

2

Thus is not a slicing issue.

In a constructor/destructor, virtual methods are not called virtually.

The rational is that the object has not been fully constructed, or has been partially destroyed. The this pointer does not point at any derived class, only to the class currently being constructed/destructed (in this case, A).

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • Actually in `OtherClass` `A::doSomething` *will* be called virtually. But since the objects dynamic type hasn't been adjusted yet (the c'tor of `A` isn't finished and the object point's to `A`s vtable), a pure virtual is called. – StoryTeller - Unslander Monica Aug 17 '16 at 05:53
  • @StoryTeller: `this->doSomething()` in constructor/destructor will be equivalent to `A::doSomething()` (so pure virtual call in OP's case) instead of `B::doSomething()`, (even if compiler choose to pass by *"modified"* vtable for that (think about diamond hierarchy)). – Jarod42 Aug 17 '16 at 10:10
  • But this isn't `this->doSomething()`. It's `anotherObj->doSoemthing()`. – StoryTeller - Unslander Monica Aug 17 '16 at 10:11
2

A's constructor invokes OtherClass's constructor, which invokes A's pure virtual method.

Unfortunately, since A's subclass, which implements this virtual method, hasn't been constructed yet, the result is undefined behavior.

Remember: superclasses get constructed before subclasses. Before B can get constructed (and thus implement the pure virtual method), it's superclass, A, needs to get constructed fully. As a part of that process, of course, A's constructor gets invoked.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • 'subclasses get constructed before superclasses'. Is that right? Base (super) classes will be constructed before derived (sub) classes. – Matthew Fisher Aug 17 '16 at 00:24