imho.ws
IMHO.WS  

Вернуться   IMHO.WS > Компьютеры > Программирование
Опции темы
Старый 30.04.2007, 11:46     # 1
crawler
Full Member
 
Регистрация: 11.12.2002
Сообщения: 864

crawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собой
таблица пойнтеров на методы разных классов

Вопрос к гуру С++ :
Имеется в наличии
Код:
void C1::m1(int );
void C1::m2(int );
void C2::m3(int );
void C2::m4(int );
- у всех методов одинаковые входные и выходные параметры

нужно сделать такой выкрутас чтобы
а) хранить таблицу пойнтеров на методы (заметьте разных классов - кастинг в пойнтер войд не предлагать)
б) в зависимисти от инпута вызывать соответсвующий метод по пойнтеру: т.е если инпут 1 - вызывать по пойнтеру на C1::m1(), а если 3 - вызывать C2::m3()

Сегодня у меня есть уже класс для вызова методов но только для одного класса, и я вызываюнужный метод по
Код:
(m_pBaseClass->*pMethod)(nIntValue)
. Как сделать это для нескольких (или хотя бы 2) классов.
Заранее спасибо.
crawler вне форума  
Старый 30.04.2007, 13:39     # 2
EvroStandart
Full Member
 
Аватар для EvroStandart
 
Регистрация: 20.01.2004
Адрес: Таллинн
Пол: Male
Сообщения: 623

EvroStandart Имеются все основания чтобы гордиться собойEvroStandart Имеются все основания чтобы гордиться собойEvroStandart Имеются все основания чтобы гордиться собойEvroStandart Имеются все основания чтобы гордиться собойEvroStandart Имеются все основания чтобы гордиться собойEvroStandart Имеются все основания чтобы гордиться собойEvroStandart Имеются все основания чтобы гордиться собойEvroStandart Имеются все основания чтобы гордиться собойEvroStandart Имеются все основания чтобы гордиться собойEvroStandart Имеются все основания чтобы гордиться собойEvroStandart Имеются все основания чтобы гордиться собой
Я конечно не гуру С++, но если у тебя куча классов с одинаковыми методами, это похоже на стандартный фабричный шаблон.

http://www.google.ee/search?hl=et&cl...&btnG=Otsi&lr=
EvroStandart вне форума  
Старый 30.04.2007, 15:10     # 3
crawler
Full Member
 
Регистрация: 11.12.2002
Сообщения: 864

crawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собой
похоже на правду. А примерчик накидать можно? как сделать
Код:
C3 executor;
executor.run(3, 18);
чтобы вызвалась C2::m3(18)

P.S. я не программер, и пример жизненно необходим. Если C1 и C2 наследники С0 - это что-то меняет?

Последний раз редактировалось crawler; 30.04.2007 в 15:14.
crawler вне форума  
Старый 30.04.2007, 16:08     # 4
Drakosha
Full Member
 
Аватар для Drakosha
 
Регистрация: 16.10.2002
Адрес: ArchLinux, Internet
Сообщения: 557

Drakosha Реально крут(а)Drakosha Реально крут(а)Drakosha Реально крут(а)Drakosha Реально крут(а)
Предложение: не надо хранить указатели на функции. Храни функторы (functor). Т.к. это нормальные объекты то делаешь наследование и всё ок.
Вот объяснение: http://en.wikipedia.org/wiki/Function_object
Drakosha вне форума  
Старый 01.05.2007, 13:51     # 5
crawler
Full Member
 
Регистрация: 11.12.2002
Сообщения: 864

crawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собой
Повторю еще раз Я -НЕ ПРОГРАММИСТ. Мне нужно сделать так, чтобы я мог запускать методы разных классов не зная их имени и порядок во время компиляции.

Фраза
Цитата:
Т.к. это нормальные объекты то делаешь наследование и всё ок
мне ничего не говорит. чем "нормальные объекты" отличаются от ненормальных ? зачем делать наследование?
Код:
class T;
class Run
{
typedef int (T::*Method)(int );
typedef struct {
    int     index
public:
    Run(T* pT)     { m_pBaseClass = pT; };

    int Call( int nMethIndex, int nParam)
        {
    int res;
    if (nMethIndex == 1)
        res = (m_pBaseClass->*m_m1)(nParam);
    if (nMethIndex == 2)
        res = (m_pBaseClass->*m_m2)(nParam) ;
    return res;
}
    void    Map( Method m1, Method m2) { m_m1 = m1; m_m2 = m2;} 
private:
    T*     m_pBaseClass;
    Method    m_m1;
    Method    m_m2;
};
Как вот это расширить на 2 класса ?

Последний раз редактировалось crawler; 01.05.2007 в 14:15.
crawler вне форума  
Старый 01.05.2007, 14:08     # 6
Drakosha
Full Member
 
Аватар для Drakosha
 
Регистрация: 16.10.2002
Адрес: ArchLinux, Internet
Сообщения: 557

Drakosha Реально крут(а)Drakosha Реально крут(а)Drakosha Реально крут(а)Drakosha Реально крут(а)
примерно так выглядят фанкторы:

Код:
class Functor {
public:
  virtual void Call(Smth & smth) = 0;
};

class FunctorA : public Functor {
public:
  virtual void Call(Smth & smth) { smth->RunA(); }
};

class FunctorB : public Functor {
public:
  virtual void Call(Smth & smth) { smth->RunB(); }
};
в таблице ты хранишь указатели: Functor*
надеюсь стало понятнее
Drakosha вне форума  
Старый 01.05.2007, 14:24     # 7
crawler
Full Member
 
Регистрация: 11.12.2002
Сообщения: 864

crawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собой
Код:
class C1;
class C2;

class FunctorA : public Functor {
public:
  virtual void Call( C1 & smth) { smth->RunA(); }
};

class FunctorB : public Functor {
public:
  virtual void Call(C2 & smth) { smth->RunB(); }
};

...

Functor fTable[2];
... fill table here
...
fTable[0].Call(); // вызов RunA(); 
fTable[1].Call();// вызов RunВ();
что-то в этом роде ?
crawler вне форума  
Старый 01.05.2007, 14:32     # 8
Drakosha
Full Member
 
Аватар для Drakosha
 
Регистрация: 16.10.2002
Адрес: ArchLinux, Internet
Сообщения: 557

Drakosha Реально крут(а)Drakosha Реально крут(а)Drakosha Реально крут(а)Drakosha Реально крут(а)
к сожалению, прототип Call должен быть одинаков во всех классах. Поэтому может так:

Код:
class C1;
class C2;

class FunctorA : public Functor {
public:
  virtual void Call( Input & input) { m_c1.Do(input); }
C1 & m_c1;
};

class FunctorB : public Functor {
public:
  virtual void Call(Input & input) { m_c2.Do(input); }
C2 & m_c2;
};
Drakosha вне форума  
Старый 01.05.2007, 18:06     # 9
crawler
Full Member
 
Регистрация: 11.12.2002
Сообщения: 864

crawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собой
чего-то слишком сложно получается... Я ведь с самого начала хотел избежать выраженного вызова m_c1.Do() Если несколько методов у каждого класса C1, C2, то как я с ними расправлюсь?
... или я чего не понимаю ?

пока додумался использовать темплейты, но как сделать для 2 классов одновременно - не понимаю

Код:
template <typename BaseClass>
class Caller
{
    typedef int (BaseClass::*Method)(int);

public:
    Caller     (BaseClass *pInstance) { m_pInstance = pInstance; }
    void        Map     ( std::string Name, Method mPtr) { m_Method[Name]= mPtr; } 
    int         Call    ( std::string Name, int param) { 
        if (m_Method.find(Name)!=m_Method.end()) 
            return  (m_pInstance->*(m_Method[Name]))(param); 
        else return 0;
    } 
private:
    std::map<std::string,Method>    m_Method;
    BaseClass                       *m_pInstance;
};
crawler вне форума  
Старый 01.05.2007, 18:14     # 10
Drakosha
Full Member
 
Аватар для Drakosha
 
Регистрация: 16.10.2002
Адрес: ArchLinux, Internet
Сообщения: 557

Drakosha Реально крут(а)Drakosha Реально крут(а)Drakosha Реально крут(а)Drakosha Реально крут(а)
Я наверное сам ничего не понимаю, запутался. У тебя есть:
class B;
class D1 : public B;
class D2 : public B;

почему бы не определить методы m... виртуальными и держа указатель на B просто вызывать их?
Drakosha вне форума  
Старый 01.05.2007, 19:58     # 11
PSyton
Junior Member
 
Аватар для PSyton
 
Регистрация: 19.04.2002
Адрес: Дом
Пол: Male
Сообщения: 187

PSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форуме
Для начала неплохо было бы понять ради чего конкретно городить огород, вообще? А уж потом решать как это организовывать. Не совсем понятная постановка задачи.
Я так понял что имеется мношество каких-то алгоритмов, которые прменяются к инту в зависимости от контекста, тогда возможно что следует просто завести множество унифицированных классов алгоритмов и сделать для них общий автоматический азпускальшик по контексту?
__________________
Дураки не динозавры - они не вымрут...
PSyton вне форума  
Старый 02.05.2007, 10:35     # 12
crawler
Full Member
 
Регистрация: 11.12.2002
Сообщения: 864

crawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собой
Для чего это нужно - я написал простенький интерпретатор, заточенный под мои нужды. У меня есть несколько алгоритмов которые применяются к интерфейс-классу параметров (в примере заменено на int). Алгоритмы запускаются один за другим в какой-то последовательности, заданной в файле конфигурации. Я читаю файл конфигурации и запускаю алгоритмы в том порядке, как в нем указано.
У меня есть несколько уже существующих классов для разных семейств алгоритмов. Пока я работаю с каким-то одним классом -все нормально, тот код что я привел в посте #9 меня полностью устраивает: там есть инстанс (я имею в виду инициализированный об'ект - пользуююсь своим жаргоном) класса, и я запускаю его методы как мне и нужно.
Но если мне надо работать с 2 классами одновременно - то мне нужно какое-то образование, чтобы держало инстансы всех нужных мне классов, и вызывало их методы в зависимости от входных данных. Надо учесть что классы алгоритмов уже написаны и их сильно менять не желательно -сегодня я просто добавил "обертку" на существующие методы, чтобы унифицировать интерфейс.
Цитата:
множество унифицированных классов алгоритмов и сделать для них общий автоматический азпускальшик по контексту
именно это я и пытаюсь сделать, но не знаю как

как бы я хотел, чтобы это выглядело в коде :
Код:
class CAlg1; // has methods m11(), m12(), m13()
class CAlg2; // has methods m11(), m12(), m13()
// all method have same declaration int mXX( int )
...
CAlg1 a1(1,2,3); // initialize class
CAlg2 a2(3,4);   // initialize class

Caller interp(a1, a2); // initialize Caller class with necessary algoritihms instances

// Set mapping from name to method
interp.Map("m11", &CAlg1::m11);
interp.Map("m12", &CAlg1::m12);
interp.Map("m13", &CAlg1::m13);
interp.Map("m21", &CAlg2::m21);
interp.Map("m22", &CAlg2::m22);
...
interp.Call("m11", 0);  // call specific algorithm
interp.Call("m21", 10);  // call specific algorithm
while ( /* read method and params from file */  )
     interp.Call(method, params);
crawler вне форума  
Старый 02.05.2007, 12:51     # 13
PSyton
Junior Member
 
Аватар для PSyton
 
Регистрация: 19.04.2002
Адрес: Дом
Пол: Male
Сообщения: 187

PSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форуме
Так и думал что это интерпретатор. :-)
Доберусь домой, попробую накропать маленький приерчик.
__________________
Дураки не динозавры - они не вымрут...

Последний раз редактировалось PSyton; 02.05.2007 в 12:56.
PSyton вне форума  
Старый 02.05.2007, 14:46     # 14
EvroStandart
Full Member
 
Аватар для EvroStandart
 
Регистрация: 20.01.2004
Адрес: Таллинн
Пол: Male
Сообщения: 623

EvroStandart Имеются все основания чтобы гордиться собойEvroStandart Имеются все основания чтобы гордиться собойEvroStandart Имеются все основания чтобы гордиться собойEvroStandart Имеются все основания чтобы гордиться собойEvroStandart Имеются все основания чтобы гордиться собойEvroStandart Имеются все основания чтобы гордиться собойEvroStandart Имеются все основания чтобы гордиться собойEvroStandart Имеются все основания чтобы гордиться собойEvroStandart Имеются все основания чтобы гордиться собойEvroStandart Имеются все основания чтобы гордиться собойEvroStandart Имеются все основания чтобы гордиться собой
Цитата:
Сообщение от crawler Посмотреть сообщение
но как сделать для 2 классов одновременно - не понимаю
http://www.codesampler.com/miscsrc.htm
Тут я нашёл простой пример фабрики с коментами.
Гугл рулит.
EvroStandart вне форума  
Старый 02.05.2007, 16:01     # 15
crawler
Full Member
 
Регистрация: 11.12.2002
Сообщения: 864

crawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собой
EvroStandart, Спасибо, но сюда фабрика не подходит. Фабрика дает выбрать какой именно об'ект инициализировать. В моем случае я должен держать инстансы обеих классов, и вызывать подходящий метод из какого-то одного. Хотя на той же странице я нашел "Chain of Responsibility Design Pattern" - это судя по всему то что мне нужно. Сча буду разбираться.
crawler вне форума  
Старый 02.05.2007, 17:29     # 16
PSyton
Junior Member
 
Аватар для PSyton
 
Регистрация: 19.04.2002
Адрес: Дом
Пол: Male
Сообщения: 187

PSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форуме
Естественно это не скомпилируется сразу - это только первые наметки, еслои так можно сказать. Суть данного метода в том что можно сделать как раз обертку на уже готовый функционал. С помощью шаблонов все это можно расширить таким образом чтобы при наследовании от уже написанного ранее класса алгоритма (не по данной схеме) его конструктор вызывался автоматом, после чего можно получить более красивые вещи, например, для регистрации алгоритмов использовать более хитрые шаблоны, более корректно проверяющие что им подают в качестве параметров шаблона...
Еще раз повторяю что все что приведено ниже это просто наметки и намеки, на то как можно сделать.
Код:
class ArgumentsList
{
private:
	//...
public:
	ArgumentsList() {}
	ArgumentsList(const ArgumentsList& other)
	{
		*this = other;
	}
	ArgumentsList &operator=(const ArgumentsList& other)
	{
		if (this != &other)
		{
			//Копируем все что надо
		}
		return *this;
	}
	~ArgumentsList() {};
};

class Results
{
public:
	Results();
	//Вся реализация конструкторы копирования и т.п.
	~Results();
};

// Базовый клас алгоритма.
class BaseAlgoritm
{
private:
	std::string m_invokedMethod;
protected:
	void dummyTest();
public:
	IBaseAlgoritm(const std::string& methodName)
		: m_invokedMethod(methodName)
	{
	}
	virtual ~IBaseAlgoritm()
	(
	)
	virtual const std::string& invikedMethod() const
	{
		return m_invokedMethod; 
	}
	virtual bool canProccess(const std::string& methodName)
	{
		return (methodName == m_invokedMethod);
	}
	virtual Results proccess(const ArgumentsList& args) = 0;
};


class Algoritm 
	: public BaseAlgoritm
{
public:
	Algoritm(const std::string& methodName)
		: BaseAlgoritm(methodName)
	{
		dummyTest();
	}
	virtual ~Algoritm()
	(
	)
};


//Предположим что есть класссы A1 и B1 которые что-то там делают... Нам нужно на их основе написать свои алгоритмы...

//Делаем наследника от A1

class AA1
	: public A1
	, public Algoritm
{
	AA1(int a, int b, int c)
		: A1(a, b, c)
		, Algoritm("m1")
	{}
	virtual ~AA1() {}
	//Реализуем функцию которая будет выполнять действия...
	virtual Results proccess(const ArgumentsList& args)
	{
		retrun A1::m1(args);
	}
};

//Аналогично для B1

class BB1
	: public B1
	, public Algoritm
{
	BB1(int a, int b)
		: B1(a, b)
		, Algoritm("m2")
	{}
	virtual ~BB1() {}
	//Реализуем функцию которая будет выполнять действия...
	virtual Results proccess(const ArgumentsList& args)
	{
		retrun B1::m2(args);
	}
};

// так далее. Суть в том что каждый наследник класса-примеси Algoritm обязан реализовать proccess, таким образом имеем общий интерфейс для все алгоритмов реализованных подобным образом.
// По идее можно не использовать примесь в виде уже реализованного класса, а просто делать наследника от Algoritm и реализовывать его соотв образом.
// Интерпретатор примет рпимерно такой вид:

class Interpret
{
private:
	typedef std::list<BaseAlgoritm *> AList;
	AList m_algoritms;
public:
	Interpret() {}
	virtual ~Interpret()
           {
		while (m_algoritms.size() > 0)
		{
			delete *(m_algoritms.begin());
                                  m_algoritms.erase(m_algoritms.begin());
		}
           }
	Results invore(const std::string &method, const ArgumentsList& args)
	{
		AList::const_iterator i = m_algoritms.begin();
		AList::const_iterator ei = m_algoritms.end();
		for (; i != ei; ++i)
		{
			if ((*i)->canProccess(method))
				return (*i)->proccess(args)
		}
		return Results();
	}
	bool contains(const std::string &method)
	{
		AList::const_iterator i = m_algoritms.begin();
		AList::const_iterator ei = m_algoritms.end();
		for (; i != ei; ++i)
		{
			if ((*i)->canProccess(method))
				return true;
		}
		return false;
	}
	template <class AT>
	void register(int a, int b, int c)
	{
		AT* newalg = new AT(a, b, c);
		if (!contains(newalg->invikedMethod()))
			m_algoritms.push_back(newalg);
                      else
                                 delete newalg;
	}
	template <class AT>
	void register(int a, int b)
	{
		AT* newalg = new AT(a, b);
		if (!contains(newalg->invikedMethod()))
			m_algoritms.push_back(newalg);
	}
};


int _tmain(int argc, _TCHAR* argv[])
{
	Interpret tmp;
	tmp.register<AA1>(10,5.3);
	tmp.register<BB1>(5,22);
	ArgumentsList lst1;
	ArgumentsList lst2;
	Results rr = tmp.invore("m1", lst1);
	Results rr1 = tmp.invore("m2", lst2);
}
__________________
Дураки не динозавры - они не вымрут...

Последний раз редактировалось PSyton; 02.05.2007 в 17:36. Причина: кое-что поправил.
PSyton вне форума  
Старый 03.05.2007, 11:23     # 17
Flexz
Newbie
 
Регистрация: 17.06.2002
Сообщения: 30

Flexz Путь к славе только начался
посмотри boost::function

конкретно вот это:
http://boost.org/doc/html/function/t...html#id2688553

PS сильно не вникал в суть дискуссии, так что может быть мимо
Flexz вне форума  
Старый 04.05.2007, 18:20     # 18
crawler
Full Member
 
Регистрация: 11.12.2002
Сообщения: 864

crawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собойcrawler Имеются все основания чтобы гордиться собой
PSyton, попытался расширить с помощь шаблонов - умудрился вышибить компайлер с ексепшеном послезавтра продолжу эксперимент - сделаю без расширения

Flexz, не это то что надо. Я тоже наткнулся на несколько решений - но чтобы их исползовать надо понять как - а весь boost написан так, что мне проще написать самому, чем разобраться как его пользовать.

--------------------------------
Сделал. В интерпретаторе хранятся пойнтеры на базисный класс, темплейтом сделал регистрацию с разным количеством входных переменных, и промежуточный класс тоже темплейтный. Вызывается виртуальные метод "Call" базисного класса, и из-за инициации наследников подходящими методами все работает.
Таким образом вызов выглядит так:
Код:
C1 c1;
C2 c2;

Interpreter i;

i.Register<C1> ( &c1, 
    "m11",&C1::m1, 
    "m12",&C1::m2,
    NULL );
i.Register<C2> ( &c2, 
    "m21",&C2::m1, 
    "m22",&C2::m2,
    "m23",&C2::m4,
    NULL );

i.Call("m23",12);
Огромное спасибо всем участникам дискуссии.

Последний раз редактировалось crawler; 14.05.2007 в 14:23. Причина: Update
crawler вне форума  


Ваши права в разделе
Вы НЕ можете создавать новые темы
Вы не можете отвечать в темах.
Вы НЕ можете прикреплять вложения
Вы НЕ можете редактировать свои сообщения

BB код Вкл.
Смайлы Вкл.
[IMG] код Выкл.
HTML код Выкл.

Быстрый переход


Часовой пояс GMT +4, время: 23:13.




Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.