2

Considering below code, when I call new(name, 10) Foo() I expect the following to happen, in that order:

  1. void* operator new(std::size_t size, QString name, int id) overload to be called
  2. Foo(QString name, int id) constructor called from above overload at this time, enough memory is allocated to my class so I can safely do and set:

    name(name), id(id)

  3. Call Foo() empty constructor and do nothing. Only here because must be implemented.

But I missing something. The member name value is empty. Would someone explain what and how to fix?

The code:

Note: QString is Qt's QString type

class Foo
{
public:
    QString name;
    int id;

    // The idea is return an already existing instance of a class with same values that
    // we are going to construct here.
    void* operator new(std::size_t size, QString name, int id)
    {
        Foo *f = getExistingInstance(name, id);

        if(f != NULL)
            return f;

        /* call to constructor Foo(QString, int) is an alias for:
         *      Foo* *p = static_cast<Foo*>(operator new(size));
         *      p->name = name;
         *      p->id = id;
         *      return p;
         * I don't think it's wrong on ambiguos in the below call to constructor, since it does use
         * operator new(std::size_t size) and Foo(QString name, int id) "methods"
         */
        return new Foo(name, id);
    }

    void* operator new(std::size_t size)
    {
        void *ptr = malloc(size);
        assert(ptr);
        return ptr;
    }

    Foo(QString name, int id)
        : name(name),
          id(id)
    {

    }

    Foo()
    {

    }

    ~Foo()
    {

    }

    QString toString()
    {
        return QString("name = %1, id = %2")
                .arg(name)
                .arg(id);
    }

    static Foo* getExistingInstance(QString name, int id)
    {
        /* not implemented yet */
        return NULL;
    }
};

How I call this:

 QString name = "BILL";
 Foo *f = new(name, 10) Foo();
 qDebug() << f->toString(); //output "name = , id = 10"
 delete f;
Jack
  • 16,276
  • 55
  • 159
  • 284
  • http://en.cppreference.com/w/cpp/language/new – Marek R Mar 04 '16 at 20:41
  • extra parameters in new operator should be used to select memory management strategy. This is useful when implementing custom container which will menage own memory. This values shouldn't be used to initialize object. – Marek R Mar 04 '16 at 20:54
  • @MarekR: The parameters passed to new operator are exactly the same that I would pass the constructor to create the object so I just pass it once – Jack Mar 04 '16 at 22:27

1 Answers1

0

Foo *f = new (name, 10) Foo; allocates memory using the overloaded ǹew operator and after that initializes the memory with a default constructed Foo (which only overwrites name but not id since id is not initialized in the defualt constructor).

You can see that by placing e.g. qDebug() << __PRETTY_FUNCTION__; in Foo's constructors.

See SO for a similar question.

Community
  • 1
  • 1
Flopp
  • 1,887
  • 14
  • 24
  • Which default constructor are you talking about the C++-generated-one or the mine? I didn't understand how the `name` value gets overrried and `id` doesn't. Both are set at constructor `Foo(QString, int)` – Jack Mar 04 '16 at 21:48
  • `Foo *f = new (name, 10) Foo;` calls your constructor `Foo()`; `Foo *f = new (name, 10) Foo(name, 10);` would call the `Foo(QString, int)` constructor. – Flopp Mar 04 '16 at 21:56
  • I was trying to initialize the membersfrom `void* operator new(std::size_t size, QString name, int id)` overload whch calls `Foo(QString, int)` constructor. In the call to `Foo()` the value is supposed to be already set so it does nothing. – Jack Mar 04 '16 at 22:03