As the answers pointed out, this is a dumb mistake I made that has nothing to do with polymorphism or smart pointer. The corrected version is in the accepted answer.
============== Original question ==================
I am trying to make smart pointer work with polymorphism. In the following prototype code, the implementation for pure virtual function Base::print() should be in the memory block of Derived object. DerivedWrap have access to the pointer to the Derived object.
Why can not DerivedWrap::print() access the function implementation?
using namespace std;
class Base 
{
public:
    virtual void print() = 0;
};
class Derived : public Base 
{
public:
    Derived(int in) : i(in) {}
    void print() {
        cout << "int is " << i << endl;
    }
private:
    int i;
};
class DerivedWrap 
{
public:
    DerivedWrap() : DerivedWrap(make_unique<Derived>(2)) {}
    DerivedWrap(unique_ptr<Base> pBase) : _pBase(move(pBase)) {}
    void print()
    {
        _pBase->print();
    }
private:
    unique_ptr<Base> _pBase;
};
int main() 
{
    DerivedWrap pDW1();
    pDW1->print(); // error: request for member ‘print’ in ‘pDW1’, which is of non-class type ‘DerivedWrap()’
    DerivedWrap pDW2(make_unique<Derived>(2));
    pDW2->print(); // error: base operand of ‘->’ has non-pointer type ‘DerivedWrap’
    return 0;
}
 
     
     
    