2

The following...

class TestClass
{
public:

    TestClass(const char* szParam, int nParam)
    : m_strParam(szParam)
    , m_nParam(nParam)
    {
        Dbg_Printf("2 param constructor - %s, %d\n", m_strParam.c_str(), m_nParam);
    }

    TestClass()
    : m_strParam("Default")
    , m_nParam(0)
    {
        Dbg_Printf("0 param constructor - %s, %d\n", m_strParam.c_str(), m_nParam);
    }

    virtual ~TestClass()
    {
        Dbg_Printf("Destructor - %s, %d\n", m_strParam.c_str(), m_nParam);
        m_strParam.clear();
        m_nParam = 0;
    }

    std::string m_strParam;
    int m_nParam;
};


void Test()
{
    Dbg_Printf("Start\n");
    {
        Dbg_Printf("Allocating 0 param TestClass\n");
        auto pTest_0Params = std::make_shared<TestClass>();
        Dbg_Printf("Done allocating, going out of scope\n");
    }

    {
        Dbg_Printf("Allocating 2 param TestClass\n");
        const char* szTest = "2 param";
        int foo = 2;
        auto pTest_2Params = std::make_shared<TestClass>(szTest, foo);
        Dbg_Printf("Done allocating, going out of scope\n");
    }
    Dbg_Printf("Done\n");
}

produces the following results

Start
Allocating 0 param TestClass
0 param constructor - Default, 0
Done allocating, going out of scope
Destructor - Default, 0
Allocating 2 param TestClass
2 param constructor - 2 param, 2
Destructor - 2 param, 2
Destructor - 2 param, 2
Done allocating, going out of scope
Destructor - 2 param, 2
Done

The 2 param call to make_shared ends up calling the destructor twice in just allocating and assigning it.

I've debugged through this again and again with breakpoints in the destructor. It is in the middle of the make_shared call in the 2 param case.

Don't see anything obviously wrong with the code. Anyone else seeing this? Ideas?

Shammi
  • 492
  • 5
  • 13
  • 2
    (1) when you are trying to trace construction and destruction, include the value of `this` in your debugging output. (2) Rule of Five: Override copy and move constructors also. It would appear that `make_shared` is making a couple of copies. Just for fun, make your class uncopyable and/or unmovable and see what happens. – Casey Jun 24 '13 at 04:45

1 Answers1

2

Do you have -std=c++11 specified?

When I compile on the desktop with:

clang++ -std=c++03 -stdlib=libc++ test.cpp

I get what you get:

Start
Allocating 0 param TestClass
0 param constructor - Default, 0
Done allocating, going out of scope
Destructor - Default, 0
Allocating 2 param TestClass
2 param constructor - 2 param, 2
Destructor - 2 param, 2
Destructor - 2 param, 2
Done allocating, going out of scope
Destructor - 2 param, 2
Done

But when I turn on -std=c++11 I get:

Start
Allocating 0 param TestClass
0 param constructor - Default, 0
Done allocating, going out of scope
Destructor - Default, 0
Allocating 2 param TestClass
2 param constructor - 2 param, 2
Done allocating, going out of scope
Destructor - 2 param, 2
Done
Howard Hinnant
  • 206,506
  • 52
  • 449
  • 577
  • I was using -std=gnu++11, -stdlib=libc++ earlier (set in XCode). Changing it to use -std=c++11 fixed it. I would have thought gnu++11 would work fine. Regardless, thanks a lot. – Shammi Jun 26 '13 at 11:37