Показать полную графическую версию : ?* Теория *? Очередные хитрые вопросы по C++
Дабы сэкономить код я написал такую хитрую вещь:
CFormList {
vector<CForm*> flist;
public:
CFormList();
~CFormList();
void add(auto_ptr<CForm>);
void erase(CForm*);
};
CFormList::~CFormList()
{
for_each(flist.begin(), flist.end(), operator delete);
}
Компилятор не ругался, но должного эффекта не получилось. Кто из нас неправ?
У меня ругается. gcc 3.4.2. Зато for_each(flist.begin(), flist.end(), ptr_fun(operator delete));вполне работает. Честно говоря, не знаю почему, просто где-то давно вычитал.
А ещё бы я забил на std::auto_ptr и использовал более умный указатель и не мучался. Что-нибудь из boost (shared_ptr?) по идее можно выдрать, или свой на коленке сваять.
А мне std::auto_ptr нравится. В примере, правда, он только для того, чтобы показать передачу владения классом. С поправкой, пожалую согласен.
gcc, c++ 3.3.2; компилится, но не работает. Если вас не затруднит, попробуйте этот код:
#include <iostream>
#include <memory>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
// gcc -o test-1 test.cpp /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/libstdc++.so
class A {
int fvalue;
static int ginstance_count;
public:
A() : fvalue(0)
{
++A::ginstance_count;
cout << "A::A()" << endl;
}
~A()
{
--A::ginstance_count;
cout << "A::~A()" << endl;
}
static void leakReport()
{
cout << ginstance_count << " instances alive" << endl;
}
};
int A::ginstance_count(0);
class List {
bool fuse_for_each;
vector<A*> flist;
public:
List(bool b) : fuse_for_each(b)
{
}
~List()
{
if (fuse_for_each)
{
for_each(flist.begin(), flist.end(), ptr_fun(operator delete));
}
else
{
while (!flist.empty())
{
delete flist.back();
flist.pop_back();
}
}
cout << "List::~List result: ";
A::leakReport();
}
void add(auto_ptr<A> pa)
{
flist.push_back(pa.release());
}
};
int main(int argc, char*argv[])
{
cout << "Entering the block (using for_each)" << endl;
{
List list(true);
list.add(auto_ptr<A>(new A()));
list.add(auto_ptr<A>(new A()));
list.add(auto_ptr<A>(new A()));
}
cout << "Left the block" << endl;
cout << "Entering the block (well-working code)" << endl;
{
List list(false);
list.add(auto_ptr<A>(new A()));
list.add(auto_ptr<A>(new A()));
list.add(auto_ptr<A>(new A()));
}
cout << "Left the block" << endl;
}
Результат:
[andrey@localhost bin]$ test-1
Entering the block (using for_each)
A::A()
A::A()
A::A()
List::~List result: 3 instances alive
Left the block
Entering the block (well-working code)
A::A()
A::A()
A::A()
A::~A()
A::~A()
A::~A()
List::~List result: 3 instances alive
Left the block
Кажется, я нечяанно ткнул в "грязный угол языка", т.к. operator delete -
единственный статический оператор, определённый для всех классов автоматически,
причём класс идентифицируется по аргументу-указателю. Непонятно, что означает
фраза ptr_fun(operator delete), т.е. &(operator delete). Для чьёго оператора
берётся адрес? List::operator delete или A::operator delete? Чей вызывается
деструктор? Непонятно, почему это откомпилировалось...
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.