Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   ?* Теория *? Очередные хитрые вопросы по C++ (http://forum.oszone.net/showthread.php?t=48923)

pva 04-05-2005 14:00 321568

?* Теория *? Очередные хитрые вопросы по 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);
}

Компилятор не ругался, но должного эффекта не получилось. Кто из нас неправ?

ivank 04-05-2005 16:34 321626

У меня ругается. gcc 3.4.2. Зато
Код:

for_each(flist.begin(), flist.end(), ptr_fun(operator delete));
вполне работает. Честно говоря, не знаю почему, просто где-то давно вычитал.

А ещё бы я забил на std::auto_ptr и использовал более умный указатель и не мучался. Что-нибудь из boost (shared_ptr?) по идее можно выдрать, или свой на коленке сваять.

pva 12-05-2005 12:44 323503

А мне std::auto_ptr нравится. В примере, правда, он только для того, чтобы показать передачу владения классом. С поправкой, пожалую согласен.

pva 17-05-2005 13:31 324918

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? Чей вызывается
деструктор? Непонятно, почему это откомпилировалось...


Время: 02:32.

Время: 02:32.
© OSzone.net 2001-