Я надеялся понять, какие внутренние копии функционального объекта делает boost :: bind. Поскольку конструкторы этих объектов, кажется, не вызываются, я предположил, что это своего рода «очень поверхностное копирование», поэтому я ввел динамическое распределение памяти, чтобы вызвать некоторые ошибки. Однако вывод во время выполнения кода ниже, по-видимому, указывает три дополнительных вызовов деструктора для внутренних копий, сделанных связыванием.
using namespace std;
using namespace boost;
class M{
int *somedata;
public:
M(){ somedata=new int[5]; cout<<"from cstr\n"; somedata[1]=0;}
~M(){cout<<"from dstr\n"; delete somedata;}
int operator()(int i){ cout<<++somedata[i]<<endl; return 0;}
};
int main()
{
M instM;
bind<int>(instM,1)();
//bind<int>(&M::operator(),&instM,1)(); //this works with no errors, of course
instM(1); //would not change the order of output
return 0;
}
На выходе ... представлены некоторые дополнительные головоломки - например. почему первое событие dstr наступает перед вызовом operator ()? Также обратите внимание на «2» перед последним неудачным вызовом деструктора.
from cstr
from dstr
1
from dstr
bind_copy(73365) malloc: *** error for object 0x1001b0: double free
*** set a breakpoint in malloc_error_break to debug
from dstr
bind_copy(73365) malloc: *** error for object 0x1001b0: double free
*** set a breakpoint in malloc_error_break to debug
2
from dstr
bind_copy(73365) malloc: *** error for object 0x1001b0: double free
*** set a breakpoint in malloc_error_break to debug
Итак, вопрос в том, может ли кто-нибудь кратко объяснить, в каком порядке и какие копии делает связывание?
... После некоторого размышления я понял, что bind просто использует (здесь по умолчанию) конструктор копирования. После предоставления какой-либо пользовательской версии этого cstr (с выделением памяти и версией копии "as-deep-as-one-желания") вывод становится чистым (как и должно быть), но загадка остается: есть three вызовы конструктора копирования. Таким образом, в этом случае boost :: bind создает три копии объекта функции. Почему и в каком порядке? (Для вложенных boost :: binding это может привести к довольно взрывному росту числа внутренних копий.)
Вывод с определенным cp-cstr и добавлением некоторых «маркеров наследия» («P» = родитель, каждый cp cstr добавляет «-C»):
from cstr P
from cp cstr P-C
from cp cstr P-C-C
from cp cstr P-C-C-C
from dstr P-C-C
P-C-C-C:1
from dstr P-C-C-C
from dstr P-C
P:1
from dstr P