Search code examples
c++oopc++17unique-ptrdynamic-cast

Can a non-const function be called using a non-const pointer and how the program will behave when two unique_ptrs point to the same objec?


The first question:

Now I have two unique_ptrs (ptrToBase and ptrToDerived) pointing to the same object (made by make_unique). So is the program behavior undefined or how will it work on destroying the two pointers?

The second one:

the pointer as_const(ptrToDerived) is constatn. how function2 can be called although it's a non-constant function

#include <iostream>
#include<vector>

using namespace std;
class Base{

    public:
    virtual void function()const{
        cout<<"\n"<<__FUNCSIG__;
    }

    virtual~Base(){cout<<"\n"<<__FUNCSIG__;}
};




class Derived : public Base
{

    public:
    int var{9};

    virtual void function()const override{
        cout<<"\n"<<__FUNCSIG__<<"\nvar: "<<var;
    }
    void function1()const{
        cout<<"\n"<<__FUNCSIG__;
    }

    void function2(){
        cout<<"\n"<<__FUNCSIG__;
    }

    virtual~Derived(){cout<<"\n"<<__FUNCSIG__;}
};



int main()
{

    //ptr of type Base* pointing to an object of type of Derived 
    unique_ptr<Base> ptrToBase {make_unique<Derived>()};

    unique_ptr<Derived> ptrToDerived {dynamic_cast<Derived*>(ptrToBase.get())};
    if (ptrToDerived) ptrToDerived->function1();

    as_const(ptrToDerived)->function2();

    return 0;
}

Solution

  • So is the program behavior undefined or how will it work on destroying the two pointers?

    Yes, it has UB because of the double destruction. Don't do this.

    the pointer as_const(ptrToDerived) is constatn. how function2 can be called although it's a non-constant function

    std::as_const will make it a const std::unique_ptr<Derived> not a std::unique_ptr<const Derived> which is why calling function2() works.

    This will on the other hand not work:

    unique_ptr<const Derived> ptrToDerived{dynamic_cast<Derived*>(ptrToBase.get())};
    
    ptrToDerived->function2();
    

    Possible compiler output:

    source>:41:29: error: passing 'const Derived' as 'this' argument discards qualifiers [-fpermissive]
    
       41 |     ptrToDerived->function2();