2

Recently I read a piece of code like this:

template <unsigned long size>
class FooBase
{
  bool m_bValid;
  char m_data[size];
};

template <class T>
class Foo : public FooBase<sizeof(T)>
{
  // it's constructor
  Foo(){};
  Foo(T const & t) {construct(t); m_bValid = (true);}

  T const * const GetT() const { return reinterpret_cast<T const * const>(m_data); }
  T * const GetT() { return reinterpret_cast<T * const>(m_data);}

  // could anyone help me understand this line??
  void construct(T const & t) {new (GetT()) T(t);}
};

I have sliced the code to make sure it's not that complicated, the main question is about the construct(T const & t) function.

What does new (GetT()) T(t); exactly means?

btw, which version of GetT() is called?

shengy
  • 9,461
  • 4
  • 37
  • 61
  • It's noteworthy that this code is extremely fragile... if the `m_data` member isn't aligned suitably for a `T` object on your specific CPU/memory architecture, then the program may crash. The alignment/packing is an implementation detail (i.e. not specified by the Standard). Specific compilers often offer pragmas/extensions to control packing. This code could be fixed by moving the `m_data[size]` member to the front of FooBase - before `m_bValid`. – Tony Delroy Oct 04 '12 at 08:16
  • @TonyD The code is sliced as I said:) actually it comes from `Game Coding Complete` the 2006 year edition, chapter 3 section 5 `optional.h`. And thanks for the compiler issue, I pay attention when I use this class. – shengy Oct 04 '12 at 08:22
  • Your `Foo<>::GetT` functions are very dangerous because of `reinterpret__cast`! – PiotrNycz Oct 04 '12 at 08:57

3 Answers3

5

What does new (GetT()) T(t); exactly means?

It is Placement new, it allows you to place an object at a particular location in memory, which is returned by Get().

which version of GetT() is called?

The Second one.
Whenever the compiler has option of choosing between a const and a non-const function, it chooses the non-const version.
Specifically, in this case as @James points out in comments:
Non-const version is given preference because the member function which calls it is non-const.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
2

That's called "Placement new".

It means that you create a new object on a given memory buffer.

new (buffer) T(); //means it will instantiate an object T in the buffer.

This allows you to have memory buffers and custom allocators, without having to request and allocate new memory from the operating system.

Read this: What uses are there for "placement new"?

Community
  • 1
  • 1
Yochai Timmer
  • 48,127
  • 24
  • 147
  • 185
1

This looks like a placement new call. Here no memory is allocated. new simply returns the address in parenthesis and calls the constructor on the object being virtually constructed.

Superman
  • 3,027
  • 1
  • 15
  • 10
  • You may want to clarify what you mean by "being virtually constructed". There's nothing "virtual" about the call, the object is fully constructed for real just like any other object instantiated via automatic storage or the ordinary `new` operator. – In silico Oct 04 '12 at 08:08