Home
Fractals
Tutorials
Books
My blog
My LinkedIn Profile

BOOKS i'm reading

Napoleon Hill Keys to Success: The 17 Principles of Personal Achievement, Napoleon Hill, ISBN: 978-0452272811
The 4-Hour Workweek: Escape 9-5, Live Anywhere, and Join the New Rich (Expanded and Updated), Timothy Ferriss, ISBN: 978-0307465351
The Fountainhead, Ayn Rand, ISBN: 0452273331
Web Hosting Canada

mailto:olivier@olivierlanglois.net

explicit destructor call in templates

08/22/07

Permalink 10:07:44 pm, by lano1106, 426 words, 4267 views   English (CA)
Categories: C++

explicit destructor call in templates

Sometimes efficient memory management is needed and to accommodate that need, the C++ language provides the placement new operator to let the user specify the location where an object is going to be instantiated. When the placement new operator is used, the user must then explicitly call the destructor.

This is all fine but I have been wondering what happens when the placement new operator is used in conjunction with templates such as in the std::vector container and when the template parameter is a scalar built-in type that obviously does not have a destructor.

I have found out that the C++ standard committee envisaged the situation and has included specification of what a compiler must do in such situation. I do not have a copy of the standard text but the section 5.2.4 (Pseudo destructor call) states that the expression p->~T() becomes a pseudo destructor call for a built-in pointer type, which does nothing.

Here is a small program that I have successfully compiled to verify that pseudo destruction works fine:

#include <iostream>

// The header file containing the declaration of the placement new operator
// according to 'The C++ Programming Language' book (section 10.4.11) but it
// compiles fine without. It must be because it is included from <iostream>
#include <new>

class TestClass
{
    public:
    TestClass() : m_x(3) {}
    ~TestClass()
    { std::cout << "TestClass destructor called"
                << std::endl; }
    void print() const
    { std::cout << "Hello " << m_x
                << std::endl; }
    private:
    int m_x;
};

template<typename T>
class PseudoTest
{
    public:
    PseudoTest() { m_pObj = new(m_buf) T; }
    ~PseudoTest() { m_pObj->~T(); }
    T *m_pObj;
    private:
    char m_buf[sizeof(T)];
};

int main(int argc, char *argv[])
{
    // First test the int case
    {
        PseudoTest<int> a;
        *a.m_pObj = 777;
        std::cout << *a.m_pObj << std::endl;
    }
    // Then if something prints out, that means that the 
    // int pseudo-destructor has been called successfully.
    {
        PseudoTest<TestClass> b;
        b.m_pObj->print();
    }
    return 0;
}

One final word, note that I have used the placement new operator on a char buffer located on the stack and, according to Herb Sutter, this is a very bad thing because this generates non portable code. He explains why in his book Exceptionnal C++ (item 30: The "Fast Pimpl" Idiom) and then presents the right way to do it but since my test program compiles and runs fine, my evil code is will be fine for the demonstration purpose of this blog entry.

Comments, Pingbacks:

No Comments/Pingbacks for this post yet...

This post has 7 feedbacks awaiting moderation...

Comments are closed for this post.

Olivier Langlois's blog

I want you to find in this blog informations about C++ programming that I had a hard time to find in the first place on the web.

December 2024
Sun Mon Tue Wed Thu Fri Sat
 << <   > >>
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        

Search

Custom Search

Misc

XML Feeds

What is RSS?

Who's Online?

  • Guest Users: 3

powered by
b2evolution