Opened 13 years ago

Closed 12 years ago

Last modified 12 years ago

#554 closed enhancement (fixed)

Document using operator new and delete for implementing clone()

Reported by: Olly Betts Owned by: Olly Betts
Priority: normal Milestone: 1.2.9
Component: Documentation Version:
Severity: normal Keywords:
Cc: Blocked By:
Blocking: Operating System: All

Description (last modified by Olly Betts)

Methods like MatchSpy::clone() return an object which has to be deallocatable with delete. If you define operator new and operator delete for your subclass then you can actually allocate objects in your implementation of the clone() method as you want and then handle deallocation appropriately via operator delete. See the first comment for example code.

This might make it feasible to implement MatchSpy::clone() in the bindings.


Original summary and description:

Complement clone() method with destroy()

Currently methods like MatchSpy::clone() return an object which has to be deallocatable with delete. If we added a virtual method:

virtual void
MatchSpy::destroy()
{
    delete this;
}

Then instead of:

delete matchspy;

Xapian could use:

matchspy->destroy();

And then subclasses of MatchSpy could allocate themselves in other ways in clone() and provide the corresponding code to deallocate the object in destroy().

This might make it feasible to implement MatchSpy::clone() in the bindings.

Marking for 1.3.0 for now.

Change History (4)

comment:1 by Olly Betts, 13 years ago

Oh, actually the user can implement operator new and operator delete in their subclass, and that approach doesn't require an extra virtual method, or the (admittedly small) overhead of calling it for each object destroyed.

This code demonstrates that this works for the situation we'd have:

#include <iostream>

using namespace std;

class Base {
    int x;
  public:
    Base(int x_) : x(x_) { }
    virtual ~Base() { }
};

class Derived : public Base {
  public:
    Derived(int x_) : Base(x_) { }

    static void* operator new(size_t size) {
        cout << "Derived::new(" << size << ")" << endl;
        return ::operator new(size);
    }

    static void operator delete(void * p, size_t size) {
        cout << "Derived::delete(" << size << ")" << endl;
        ::operator delete(p);
    }
};

int main() {
    Base * o = new Derived(42);
    delete o;
}

This trick probably also opens the way to wrapping Xapian::Weight (#401).

comment:2 by Olly Betts, 12 years ago

Component: Library APIDocumentation
Description: modified (diff)
Status: newassigned
Summary: Complement clone() method with destroy()Document using operator new and delete for implementing clone()

So that means we need to document this technique somewhere appropriate (so updating summary and description), and link to this from the notes in the doxygen comments such as:

Note that the returned object will be deallocated by Xapian after use with "delete". It must therefore have been allocated with "new".

And then implement MatchSpy::clone() etc in the bindings.

comment:3 by Olly Betts, 12 years ago

Resolution: fixed
Status: assignedclosed

Documented in r16326.

comment:4 by Olly Betts, 12 years ago

Milestone: 1.3.01.2.9

Backported for 1.2.9 in r16364.

Note: See TracTickets for help on using tickets.