powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / C++ & Java
25 сообщений из 160, страница 4 из 7
C++ & Java
    #32854690
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
всегда приятно почитать, что пишут люди с фантазией :)
...
Рейтинг: 0 / 0
C++ & Java
    #32854843
Lepsik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей ИльичО, Лепрозорик! Привет, проказник!


мы вроде бы не пили на брудершафт

Сергей Ильич
Ну, пусть будет так. Устами дилетантов глаголет истина.

Вообще это твой стиль - сыпать какими-то терминами типа "мультиметод, функтор, абстрактная фабрика, политика etc"


Это термины видимо дилетанты типа Алескандруску придумали, чтобы профессионалов мучать


Lepsik
Не ошибусь, если скажу что 90% софта на вашем компьютере написано на С++.

--Мои рабочие тулзы - IDEA и Together - написаны на Java.

а остальные 95% программ на вашем компьютере ?


Lepsik
Сергей Ильич
Вот так вот. Создаю какой-то долгоживущий (и наверное соответственно большой) объект в куче,
у которого есть поля из бустовых классов, а какое-то бустовое поле возьми да и кинь екзепшен во
время конструирования.


вы о чем ? что такое конструирование ?

Чего - не скомпилировалась мысль в голове ? С чем поведешься, оттого и наберешься.

--Я вообще о работе конструктора (конструирование == работа конструктора). Понял?

только сначало надо сеть в песочницу с вами тыкать в каждый предмет и спрашивать как он называется на вашем языке.


--Когда я был на курсах по Джаве, мой руководитель мне дал задание - сделать два потока - один будет

С++ я так понял тоже на уровне курсов остался ?
дожились - программирование на курсах изучают. После вождения грузовиков надо полагать ?

Сергей Ильич
Показал отделу кадров - вместе посмеялись.
Они помнят, как по всему Питеру было не найти человека подходящего уровня. Искали год.
А компания у нас большая. Специализация - IT.


а вы как в IT сектор попали ? я так понял судя по курсам из другой отрасли ?

--Видимо могучий Лепсик пишет вообше без ошибок.

конечно бывают, как же без них ?

Сергей ИльичПотому что исключения в С++ сделаны через жопу.
может не умеете ими пользоваться ?[/quot]
В прошлый раз благодаря такому аргументу мы пришли к выводу, что чтобы пользоваться
произведением бездушной системы документирования javadoc не нужно умение, в противоположность
документации от Борланд. Видимо, Борланд очень много души вкладывает в свою документацию.[/quot]



Код: plaintext
1.
2.
3.
Syntax
catch (exception-declaration) compound-statement
Description
The exception handler is indicated by the catch keyword. The handler must be used immediately after the statements marked by the try keyword. The keyword catch can also occur immediately after another catch. Each handler will only evaluate an exception that matches, or can be converted to, the type specified in its argument list.

честно говоря даже не знаю чего можно добавить к этим трем явно избыточным предложениям, чтобы понять как правильно исключениями пользоваться .
...
Рейтинг: 0 / 0
C++ & Java
    #32854913
c127
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сергей Ильич> О, Лепрозорик! Привет, проказник!
NotGonnaGetUs> всегда приятно почитать, что пишут люди с фантазией :)

Эт точно, полет фантазии высок, а мысли глубоки.
...
Рейтинг: 0 / 0
C++ & Java
    #32855565
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
Сергей ИльичКем гарантируется ? Стандартом или конкретным компилятором ? гарантируется стандартом. вот вам пример из MSVC
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
class One{
	int i_;
public:
	One() : i_( 0 ) { printf("construct One;\n"); }
	~One() { printf("destruct One;\n"); }

	void* operator new( std::size_t Count ) { 
		printf("One operator new\n");
		return ::operator new(Count); 
	}
	void operator delete( void* ptr ){
		printf("One operator delete\n");
		::operator delete( ptr );
	}
};

class Two{
	int i_;
public:
	Two() : i_( 0 ) { printf("raise Two;\n"); *static_cast<char*>( 0 )= 0 ; }

	void* operator new( std::size_t Count ) { 
		printf("Two operator new\n");
		return ::operator new(Count); 
	}
	void operator delete( void* ptr ){
		printf("Two operator delete\n");
		::operator delete( ptr );
	}
};

struct Three1{
	One one_;
	Two two_;

	Three1() : one_(), two_() {}

	void* operator new( std::size_t Count ) { 
		printf("Three1 operator new\n");
		return ::operator new(Count); 
	}
	void operator delete( void* ptr ){
		printf("Three1 operator delete\n");
		::operator delete( ptr );
	}
};

struct Three2{
	std::auto_ptr<One> one_;
	std::auto_ptr<Two> two_;

	Three2() : one_(new One), two_(new Two) {}

	void* operator new( std::size_t Count ) { 
		printf("Three2 operator new\n");
		return ::operator new(Count); 
	}
	void operator delete( void* ptr ){
		printf("Three2 operator delete\n");
		::operator delete( ptr );
	}
};

int main()
{
    //Three1* t1( new Three1 );
	Three2 *t2( new Three2 );
    
	return  0 ;
}
все замечательно работает.


Сергей ИльичНикто не сможет поместить в этот контейнер объект другого типа. Для этого понадобился бы С-Style cast или reinterpret_cast. А против лома не приема.
В некоторых языках программирования, в которых нет generic programming, т.е. шаблонов и иже с ними, реализовывались классы контейнеров содержащие либо нетипизированные указатели, либо некий TObject от которого наследуются ВСЕ другие классы в языке, либо используют variant или что-то на него похожее. Итак, я беру в таком языке контейнер и хочу разместить в нем свой тип например TPoint. Ну и всякий раз чтобы к обращаться к членам этого класса в контейнере мне надо прибегать к преобразованиям типов. Уже постов 10 наверное я вам об этом говорю, но вы упорно игнорируете это и пытаетесь впарить мне что-то другое.

В случае с шаблонами мне не придется прибегать к преобразованиям типов. Такой вариант будет намного безопасней, чем вариант с контейнером нетипизированных указателей или с элементами типа TObject. Написание же своих контейнеров для каждого класса - очень неблагодарное занятие.

Сергей ИльичНету никакого generic programming.Бредит бедняга. Лишь бы несогласится во всем. Это как люди которые не признают что есть ООП. Понимаешь ява-фан, мне пофиг какой термин зреет у тебя в голове при виде шаблонов и приемов их использования. Для меня и для многих других программистов это значит generic programming. Пусть он будет синонимом того словосочетания, который ты так яростно предложил. Но спор о терминах непродуктивен. Обычно на него сбевается человек, у которого кончились аргументы.

И вообще разговор с тобой стал беспредментым. Он перешел с обсуждения того, что есть другие парадигмы программирования кроме ООП, на флейм о сравнении языков. Он бессмысленен, потому что технологии использования инструментов (языков) разные. Использовать подход ЯВЫ к С++ глупо, как и наоборот. Если возвращаться к частностям, то аргументы которые вы выдвинули против generic programming оказались лживыми, связанные с непониманием этого вопроса лично вами. А окончательный ваш аргумент - generic programming не существует. Следующим вашим шагом будет - шаблонов тоже нет, это макросы Си. И ваще весь мир иллюзия, ну и т.д. Очень продуктивно...

Сергей ИльичПо умолчанию каждый объект к Яве равен только самому себе (дефолтовая реализация eqals в java.lang.Object сравнивает указатели на объекты). Можно его перегрузить, чтобы сравнивать тождество содержимого объектов. Но в объектах - хандлерах лучше этот метод не трогать.
ставим галочку сравнить функторы в Яве нельзя. ясно. ваш ответ понятен.

Сергей ИльичСтатический метод Collections.sort(...) может отсортировать любую последовательность содержащую объекты любых типов. И там не надо ничего переписывать. Не вижу никаких проблем с поздним связыванием (он делает downcasting к типу Comparable). В любом случае, пространства для нетривиального бага тут нет. В конце концов, operator< тоже можно неправильно перегрузить.
оооо, какая маленькая частность!!! какие чудеса. и это доказывает что? что шаблоны не нужны. Ну вы сделали революцию. А теперь попробуйте сделать еще один шаг дальше. С тем же подходом напишите контейнер для любых классов. Ну я имею ввиду, что элементы однотипны, но могут быть объектами разных классов.

Сергей Ильичкакие функциональные кирпичи программы кроме контейнеров ты можешь себе представить? понимаешь, я так часто повторяю о реализации контейнеров, как наглядном примере использования generic programming. Ты это упорно пропускаешь мимо ушей. Говоря о чем-то своем. Но изначально речь зашла о шаблонах и ты высказался что они есть очень-очень плохо и не нужны вовсе. Я попросил аргументировать. На выдвигаемые тобой аргументы я ответил. Твои аргументы кончились, теперь ты обвиняешь меня в зациклинности, хотя сам ингорировал, то что я тебе говорил о преимуществах generic programming. О том что у любого решения есть плюсы и минусы, и что надо выбирать нечто оптимальное. Это можно сделать только в условиях КОНКРЕТНОЙ ЗАДАЧИ, а не с философской точки зрения. ВОТ Я ТЕБЕ ОПЯТЬ предлагаю конретную задачу - контейнер объектов любого класса. Забудем про контейнер функторов для реализации делегатов. Вернемся просто к контейнерам.

Сергей ИльичВ конце концов, каждый кандидат на роль содержимого контейнера STL должен быть assignable и copy constructable. Если подумать, на эти обязательства довольно сложно подписаться в случае нетривиальных объектов. Не вижу ничего сложного, абсолютно! приведите ваш пример, а пока приведу свой.
Код: plaintext
1.
2.
struct TPoint{
 int x,y;
}
все - этот объект готов к размещению в контейнере. ну давайте посложней
Код: plaintext
1.
2.
3.
4.
class TCircle{
 TPoint center_;
 float radius_;
}
тоже самое. Это объект можно размещать в контейнере. Сложно? да нет.

Сергей ИльичПочему не надо? кто-то заявил, что он кидает только SomeException (throw SomeException), он вызал мой метод, мой метод вызвал какой-то калбэк из внутренней коллекции. А этот калбэк кинул SomeOtherException. По идее, соглашение о кидании только SomeException нарушено, поэтому должен быть вызван unexpected(), который по умолчанию сводится к terminate().
Ты знаешь, не боюсь повторится - на те приемы, которые использует специалист в своей работе, накладывает отпечаток опыт применения какого-либо инструмента. о чем я? да о специализации исключений. Оно уже убрано в новом черновом стандарте С++. В 4 современных компиляторах, на него компилеры выдают варнинг. ДОстаточно опытный программист С++ знает те минусы их использования. Это определенный стиль программирования. Ниже я приведу реализацию СТЕКА без единого try catch, но который работает корректно, не разрушая себя или то что в нем хранится, если генерируется исключение. приведу пример, только чтобы показать, что есть другой подход в обработке исключений.

Сергей ИльичЯ знаю значение этих терминов, но они были упомянуты явно не к месту. они были упомянуты к месту. ПОВТОРЮ. Тобой было сказано, что книга Александреску не имеет практического применения, в ответ я упомянул о реализации фабрик, мультиметодов и прочего. И то что они как раз имеют практическое применение. Я не сравнивал это с друнгими реализациями, и не говорил что книга Александреску является единственной книгой о паттернах программирования. Вы передергиваете и переиначиваете мои слова. Я ВЫСКАЗАЛ СВОЙ АРГУМЕНТ в ответ на ваше поспешную фразу. Так же я сказал, что это книга является хорошим примером ЭФФЕКТИВНОГО использования шаблонов в применении к паттернам проектирования. Вы не стали ничего говорить в ответ, а лишь сыпали высказываниями что я бросаюсь какими-то терминами и чего-то жду. Что я их говорю не к месту. Ну и т.д. и т.п. Т.е. обычные общие эмоциональные фразы. Если хотите продуктивного разговора - давайте возьмем у Александреску реализацию визитера и разберем его по полочкам, что там плохого, и что хорошего. (боюсь мне этого от вас никогда не дождаться). Чтобы вы востержроствовали в плане доказательств бесперспективности использования шаблонов. Вы же читали эту книгу, значит помните все, ну или основные минусы, той реализации которую встретили. Мне очень интересно их услышать. я весь внимание.

Сергей ИльичНаверное, с помошью шаблонов можно проэмулировать наличие таких вещей в С++, но тогда придется отказаться от раздельной компиляции. Ну не собрать шаблонный класс в *.obj. Никак. Я говорил об этом. Да для шаблонов нельзя сделать закрытую реализацию. Только ответ на непонимание книги Александреску прозвучал совсем в другом месте. Эти вопросы никак не связаны. Только я хочу сделать мааааленькую оговорочку.

ДОпустим вы имеете несколько классов и вам надо реализовать несколько мультиметодов для них. Или построить везетера. Вам не надо открывать реализацию этих классов. Открыта всего лишь реализация класса шаблона везетера. Если вы хотите считать это минусом - считайте. Переубеждать вас не буду. Еще раз повторюсь - любое решение содержит плюсы и минусы. Надо выбирать оптимальное.

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

Мое предложение, либо давайте говорить о КОНКРЕТНЫХ ВЕЩАХ - фрагменты кода с указанием плюсов и минусов( показав на примере более более оптимального решения). Либо оставьте эту тему в покое.

(а пока напишу реализацию стека)
...
Рейтинг: 0 / 0
C++ & Java
    #32855570
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
насчет Exception Specifications рекомендую пока ознакомится здесь .
...
Рейтинг: 0 / 0
C++ & Java
    #32855635
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
Итак, цитируя Саттера, в 1994 году Том Каргилл опубликовал статью "Exception Handling: A False Sense of Security" (кажется в журнале C++ Report). Он убидительно показал, что в то время программисты С++ не совсем хорошо понимали как следует писать безопасный в смысле исключений код...

Каргилл предложил всем читателям найти полное решение поставленной им задачи. Хотя изначально речь шла не о шаблонах, а просто некий класс widget. Ну не важно...
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
    
    template <class T>
    // T must have default ctor and copy assignment
    class Stack
    {
    public:
        Stack();
        ~Stack();
        Stack(const Stack&);
        Stack& operator=(const Stack&);

        unsigned Count();   // returns # of T's in the stack
        void     Push(const T&);
        T        Pop();     // if empty, returns default-
                            // constructed T

    private:
        T*       v_;        // pointer to a memory area big
                            //  enough for 'vsize_' T objects
        unsigned vsize_;    // the size of the 'v_' area
        unsigned vused_;    // the number of T's actually
                            //  used in the 'v_' area
    };
Надо было предоставить реализацию этого класса со "строгой гарантией" ,безопасности исключений (сформулированную Дейвом Абрахомсом). Через три года решение было предоставлено и были внесены соответсвующие изминения в стандарт языка. Вот решение
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
template<class T1, class T2>
void construct( T1* p, const T2& value ){
 new(p) T1( value );
}

template<class T>
void destroy( T* p ){
  p->~T();
}

template<class FwdIter>
void destroy( FwdIter first, FwdIter last ){
 while( first != last ){
   destroy( &*first);
   ++first;
 }
}

// идеома pimpl
template<class T>
class StackImpl{
protected:
 StackImpl(size_t size =  0 );
 ~StackImpl();
 void Swap( StackImpl& other );
 T* v_;
 size_t vsize_;
 size_t vused_;
private:
 StackImpl( const StackImpl& );
 StackImpl& operator = ( const StackImpl& );
};


template<class T>
StackImpl<T>::StackImpl( size_t size )
// запрещаем вызов конструкторов по умолчанию
     : v_( static_cast<T*>(size== 0 ?  0  : operator new( sizeof(T)*size ) ) ),
       vsize_(size),
       vused_( 0 )
{
}

template<class T>
StackImpl<T>::~StackImpl(){
 destroy( v_, v_ + vused_ );
 operator delete( v_ );
}

template<class T>
void StackImpl<T>::Swap( StackImpl &other ){
  std::swap( v_, other.v_ );
  std::swap( vsize_, other.vsize_ );
  std::swap( vused_, other.vused_ );
}

тут возможны две реализации идеомы pimpl:
1) указатель на реализацию, тогда члены реализации стека должны быть public
2) наследование, тогда ничего менять не надо

данная реализация соотвествует строгой гарантии безопасности исключений. Теперь коротко о самом стеке.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
template<class T>
class Stack : private StackImpl<T>
{
 public:
   Stack( size_t size =  0  ) : StackImpl<T>(size) {};
   // деструктор не нужен
  Stack( const Stack& );
  Stack& operator = (const Stack temp ) { Swap(temp); return *this; }
  size_t Count() const { return vused_; }
  void Push( const T& );
  T& Top();
  void Pop();
}

вобче-то дальше ужо можно не приводить методы, потому что идея понятна уже по реализации оператора присваивания. Но дальше процитирую кратко остальные методы, для краткости без проверки границ и размеров стека. просто для краткости
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
Stack( const Stack& other )
       : StackImpl<T>(other.vused_)
{
   while( vused_ < other.vused_ ){
         construct( v_ + vused_, other.v_[vused_] );
         ++vused_;
   }
}

void Push(const T& t )
{
   if( vused_ == vsize_ ){
       Stack temp( vsize_* 2  +  1  );

       while( temp.Count() < vused_ ) temp.Push( v_[temp.Count()] );
       temp.Push( t );
       Swap( temp );
   } else {
       construct( v_ + vused_, t );
       ++vused_;
   }
}
остальные методы не вижу смысла приводить здесь. Суть уловили? Мы обошлись без блоков try catch, но это не значит что они не нужны. Важно уловить суть написания безопасных классов.

Далее о спецификациях исключений.
...
Рейтинг: 0 / 0
C++ & Java
    #32855643
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cорри, что вмешиваюсь :)
dwl
Сергей Ильич
Никто не сможет поместить в этот контейнер объект другого типа. Для этого понадобился бы С-Style cast или reinterpret_cast. А против лома не приема.

В некоторых языках программирования, в которых нет generic programming, т.е. шаблонов и иже с ними, реализовывались классы контейнеров содержащие либо нетипизированные указатели, либо некий TObject от которого наследуются ВСЕ другие классы в языке, либо используют variant или что-то на него похожее. Итак, я беру в таком языке контейнер и хочу разместить в нем свой тип например TPoint. Ну и всякий раз чтобы к обращаться к членам этого класса в контейнере мне надо прибегать к преобразованиям типов. Уже постов 10 наверное я вам об этом говорю, но вы упорно игнорируете это и пытаетесь впарить мне что-то другое.


1. С.Ильич говорит об этом:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
   class  MyCollection {
        Vector v =  new  Vector();
         void  add(MyObj o){
              v.add(o);
        }
        MyObj get( int  i) {
               return  (MyObj)v.get(i);
        }
  }
Поместить объект не того типа - не получится.
Каст - безопасен, если MyCollection реализован корректно.

2. А начиная с java1.5.
Можно писать
Код: plaintext
1.
2.
3.
Vector<MyObj> v = ... ;
  ... 
MyObj obj = v.get(i);
Т.е. нет никаких проблем с помещение однотипных объектов в коллекции.
Проверка типов гарантируется на этапе написания кода.

3. В чём на самом деле плюсы С++ generetics, если это новая технология програминга? :)
...
Рейтинг: 0 / 0
C++ & Java
    #32855649
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
т.е. генерик програминг.
...
Рейтинг: 0 / 0
C++ & Java
    #32855655
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
Более подробно о гадости спецификации исключений для функций можно прочесть в еще одной интересной статье Саттера - ТУТ .

Если кратко пересказывать то получится вот что:
- Указание throw() ограничит в будущем ваши возможности по изминению кода этих функций - вы не будете иметь права генерировать исключения. Изминение спецификации исключений несет риск нанесения вреда клиенту который юзает эту функцию и расчитывает что она не выпускает исключений.
- Спецификации исключений могут привести к повышенным накладным расходам независимо от того, генерируется ли на самом деле исеключение или нет. Например такой оператор перестанет быть инлайновым:
Код: plaintext
T& operator*() const throw()  { return *ptr; }

Более придирчивые могут заметить, что весь тот класс стека, что я процитировал, основан на одном допущении что деструкторы не генерят исключений. Да. Есть такое соглашение. И я не вижу ничего плохого в нем. Если класс нельзя безопасно разрушить, тогда раскрутка стека станет невозможной. И никакой try catch здесь не поможет. Если кому интересно можно об этом рассказать.

PS: кстати, задача Каргилла была решена при помощи указателя на клас-реализацию. Указатель был одет в std::auto_ptr
...
Рейтинг: 0 / 0
C++ & Java
    #32855676
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
Очень рад что "вдруг" начали подтягиваться силы с Ява форума, чтобы закопать гадких С++ программеров. Еще раз повторю мысль высказанную на первой страничке темы - сравнение языков - флейм и тему надо закрывать. Лично я потерял к ней всякий интерес.

NotGonnaGetUs1. С.Ильич говорит об этом: А я об этом
Код: plaintext
 return (MyObj)v.get(i);
о том, что шаблоны позволяют избегать преобразований типов. Т.е. познего(динамического) связывания. Динамическое связывание переносит проверку ошибок на момент отладки, т.е. рантайм. В случае использования шаблонов подобные ошибки обнаруживаются на этапе компиляции. Далее в таком контейнере могут лежать только классы с виртульаным деструктором. Хотя в случае если за вами приберает машина - это не имеет значение. Это первое. Второе у меня есть ОДИН КЛАСС контейнер и мне не надо переписывать что либо, т.е. писать MyCollection, чтобы получить доступ к елементам контейнера. Это улучшает повтороное использование кода и ускоряет написание программ. Третье шаблоны позволяют расширять возможности языка без добавления новых фич и принятия новых стандартов. Хотя это не значит, что фичи не нужны.

Все эти вещи я писал в своих предыдущих сообщениях. Если каждый посетитель форума Явы будет приходить в эту ветку не читая ее содержимого и задавать один и тот же вопрос - "чем же это лучше?". То мне вскоре надоест отвечать. Это будет результат 8-)

NotGonnaGetUs2. А начиная с java1.5. Можно писать... Об этом я тоже писал, сказав о том, что это лишний раз доказывает перпективность такого подхода в разарботке, который продемонстрировали шаблоны в С++.

NotGonnaGetUs3. В чём на самом деле плюсы С++ generetics, если это новая технология програминга? :)
Технология, парадигма, как хотите...
1) лучшая защита типов
2) статическое связывание типов, что позволяет повторно использовать большее кол-ва кода, нежели ТОЛЬКО при помощи ООП.
3) возможность написание алгоритмов без привязки к реализации того или иного типа. Пример алгоритмы STL. А также например умные указатели.
4) делает код более быстрым, потому что в случае со статическим связыванием типов, многие вещи инстанцируются инлайново плюс этим(инстанцированием) можно управлять. Пример я уже приводил, при помощи классов-шаблонов выражений была написана билиотека, которая реализует алгоритмы линейной алгебры быстрее чем аналогичная на Фортране. До этого никто не мог "побить" этот фортрановский рекорд. Он держался десятки лет. Подробне смотри std::valarray, boost::uBLASt, библиотеки biltz (вроде бы так) и MTL (matrix template library).


Это если вобчем.

Ну я понимаю, что контейнеры уже всем надоели - приведу другой пример. Пример совместного использования шаблонов и ООП. В яве такой(их) задач безусловно не возникнет:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
// пример с умными указателями пропущу. Но не представляю как ЛУЧШЕ это сделать в ООП
template<class T>
class SmartPrt{
  T* ptr_;
  
  // запретить преобразование типов
  template<class U>
  operator U();

  // запретить операцию присвоения
  template<class U>
  T& operator =( U& );
public:
  SmartPtr( T* other ) : ptr_( other ) {}
  ~SmartPtr() { ptr->~T(); } // вызываем дуструктор нужного типа
  T* operator ->() const { return ptr_; }
  T& operator *() const { return *ptr; }
}

// ну или - например хочу написать счетчик объектов того или иного класса
// для этого мне надо написать тоьлко один класс, в случае реализации ООП, она будет более громоздкой
template<class T>
class ObjectCounter{
private:
   static size_t count;
protected:
   ObjectCounter() { ++ObjectCounter<T>::count; }
   ObjectCounter( ObjectCounter<T> const& ) { ++ObjectCounter<T>::count; }
   ~ObjectCounter() { --ObjectCounter<T>::count; }
public:
   static size_t live() { return ObjectCounter<T>::count; }
}

template<class T>
size_t ObjectCounter<T>::count =  0 ;
далее для ЛЮБОГО класса можно сделать так и ничего при это не надо переписывать или добавлять новых структур данных, при этом сохранив строгую проверку типов.
Код: plaintext
 class MyType : public ObjectCounter<MyType> 
как видите объект даже не стал шаблоном. Для него можно сделать закрытую реализацию. И изминять почти ничего не пришлось.

Следующим постом другие примеры
...
Рейтинг: 0 / 0
C++ & Java
    #32855692
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
Если кто-то предыдущие примеры считает не удобными или не наглядными приведу еще пару примеров (такие задачи могут и не возникнуть в рамках другого языка, что лишний раз доказывает что сравнивать языки глупо ). Эти примеры показывают как шаблоны раздвигают возможности КОНКРЕТНО ЯЗЫКА С++.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
//как сделать класс, который нельзя наследовать
// вот решение для любого класса
template <class T> class NotInherit; // форвардим чтобы друга объявить

template <class T> 
class NotInheritImpl
{
  friend class T;
  friend class NotInherit<T>;

private:
  NotInheritImpl() {}
};

template <class T> 
class NotInherit : private virtual NotInheritImpl<T> {};

// Пример 
class MyType : NotInherit<MyType>
{
  // этот класс нельзя наследовать
};

NotInherit можно применить к любому существующему классу проекта С++. Есть еще одна удобная штучка STATIC_ASSERT, можно заставить компилятор заткнуться в нужном месте СООБЩИВ определенный текст что вам нужен. Средствами ООП это ваще не реализуется.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
template<bool> struct CompilerTimeChecker{
  CompilerTimeChecker(...); // т.е. произвольное кол-во аргументов
};

template<> struct compileTimeChecker<false> {};

#define STATIC_CHECK(expr, msg)\
{\
class ERROR_##msg {};\
(void)sizeof(CompileTimeChecker<(expr) !=  0  >((ERROR_##msg())));\
}
ну кончено сообщения могут быть только на английском, типа того STATIC_CHECK( sizeof(From) <= sizeof(To), Destination_Type_Too_Narrow ) . Удобно. Кстати в BOOST пошли дальше. Одна из областей применения такого ассерта concept_check , когда класс или функция проверяет, а выполняются ли нудные требования для типа. Если не выполняются - генерить ошибку компиляции.

Например
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
#include <list>
#include <algorithm>

int main(int, char*[]) {
    std::list<int> v;
    std::stable_sort(v.begin(), v.end());
    return  0 ;
}
Если добавить в эту программу concept_check, тогда длинные и столь нелюбимые стандартные ошибки, например об отсуствии оператора меньше
Код: plaintext
1.
2.
3.
stl_algo.h: In function `void __merge_sort_loop<_List_iterator
  <int,int &,int *>, int *, int>(_List_iterator<int,int &,int *>,
  _List_iterator<int,int &,int *>, int *, int)':
превращаются в более удобный вид
Код: plaintext
1.
boost/concept_check.hpp: In method `void LessThanComparableConcept
  <_List_iterator<int,int &,int *> >::constraints()':

Используя шаблоны я могу сделать виртульаность метода класса ПАРАМЕТРИЗИРОВАННЫМ. Т.е. какие-то классы наследуют от родителя виртуальный класс, а какие-то нет. Используя шаблоны я могу определить какой тип передается шаблону. Причем сделать это можно на этапе компиляции без RTTI. Используя шаблоны можно определить есть ли нуный метод у класса или нет, и в зависимости от результата что-то предпринять. Например, так действует "определитель", что тип является POD, а не классом. При помощи шалонов можно реализовать такую замечательную вещь как списки типов. Используя их можно получить более элегантную реализацию Визитера, чем ЛЕС dynamic_cast ( ну или операторов T is MyType ). Перечислять можно долго.

Еще раз повторюсь, что в других языках возможно таких вопросов и не возникает. Такие задачи могут быть поставлены и решены в С++. Поэтому раз мы рассматриваем шаблоны С++, то я и говорю в ДАННЫЙ момент о пользе их для С++. О более общих плюсах я уже говорил в других постах.
...
Рейтинг: 0 / 0
C++ & Java
    #32855848
c127
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
2 NotGonnaGetUs

>Т.е. нет никаких проблем с помещение однотипных объектов в коллекции.
Проверка типов гарантируется на этапе написания кода.


Этап написания кода это хорошо сказано. А если код пишется на бумаге проверка типов тоже гарантируется?
...
Рейтинг: 0 / 0
C++ & Java
    #32856004
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
c1272 NotGonnaGetUs

>Т.е. нет никаких проблем с помещение однотипных объектов в коллекции.
Проверка типов гарантируется на этапе написания кода.


Этап написания кода это хорошо сказано. А если код пишется на бумаге проверка типов тоже гарантируется?

%)
Для самых остроумных поясню. Речь о том, что не обязательно компилировать приложение, что бы получить сообщения об ошибке. IDE 99% ошибок возникающих на этапе компиляции подсвечивают при наборе кода.

Разве в c++ не тоже самое? Или с-шный код на бумаге всегда пишется правильно? :)
...
Рейтинг: 0 / 0
C++ & Java
    #32856008
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
ну понеслась...
здесь уже стали IDE сравнивать - чистоганом флейм попер.

ЗЫЖ если кому интересно чисто в качестве эрудиции, лично у меня в MSVC 2003 ошибки "подсвечиваются". Хотя это не показатель. У меня есть подобные надстройки для делфи, для буилдера, для бейсика. и что теперь? что-то изменилась в ваших взглядах?
...
Рейтинг: 0 / 0
C++ & Java
    #32856030
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwlОчень рад что "вдруг" начали подтягиваться силы с Ява форума, чтобы закопать гадких С++ программеров.

Ну зачем так грубо :) Лично я, всех программеров люблю одинаково.
(Даже тех кто-пишет на php ^_^)


NotGonnaGetUs1. С.Ильич говорит об этом: А я об этом
Код: plaintext
 return (MyObj)v.get(i);
о том, что шаблоны позволяют избегать преобразований типов. Т.е. познего(динамического) связывания.

Пример Ильича как раз показывает, что можно обойтись без позднего динамического связывания введением подобных конструкций (MyCollection).
Я не спорю, generic удобен тем, что позволяет описать теже самые конструкции, только класс "MyObj" становится в них параметром, а не жестко заданным.
Да, это сокращает кол-во кода, который нужно написать.
С этим никто не спорил.
Я спросил какие ещё плюсы даёт С++ generic.
Если всё дело только в выше описанном - не понятно зачем "генерик" ставить на один уровень с "ооп".


Третье шаблоны позволяют расширять возможности языка без добавления новых фич и принятия новых стандартов. Хотя это не значит, что фичи не нужны.

Не много не понял о чём речь. Шаблоны позволяют вместо одного стандарта сделать десять разных и потом учить им каждого нового программиста в проекте? Тогда стронняя библиотека тоже является расширением стандарта языка? :)

Если каждый посетитель форума Явы будет приходить в эту ветку не читая ее содержимого и задавать один и тот же вопрос - "чем же это лучше?".

Я дня три регулярно перечитывал ветку :) Просто мне показалось что вы отвечаете друг другу одно и тоже из-за не допонимания и попытлся показать в чём оно :(

---

Ответ на свой вопрос я получил, спасибо :)

"Общие плюсы" от С++ generic = плюсы от java generic + interfaces.

Остальные проблемы решаемые шаблонами уникальны для языка С++, а не для программирования как такового.

Далее одна субъективность: что лучше учить язык пару лет и постоянно обнаруживать в нём новые тонкости или выучить его за пару месяцев и просто писать код? :) Тут конечно же на любителя.

з.ы. У меня тоже нет желания вести флейм :)
...
Рейтинг: 0 / 0
C++ & Java
    #32856034
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwlну понеслась...
здесь уже стали IDE сравнивать - чистоганом флейм попер.


Я тоже удивился реакции c127 :)
Речь не про IDE, а про ошибки на стадии компиляции.
...
Рейтинг: 0 / 0
C++ & Java
    #32856040
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
NotGonnaGetUsРечь не про IDE, а про ошибки на стадии компиляции.Ну и я о них. Сто раз уже говорил, что преобразования типов уменьшают кол-во таких ошибок откладывая их проверку на рантайм. Использование шаблонов наоборот увеличивает кол-во ситауция которых можно проверить на этапе компиляции.

Например, используя шаблоны я могу определить является ли тип встроенным, или является ли один класс наследником другого. На этапе компиляции а не рантайм. Попробуйте это сделать обычными средставми ООП.
...
Рейтинг: 0 / 0
C++ & Java
    #32856046
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwlНапример, используя шаблоны я могу определить является ли тип встроенным, или является ли один класс наследником другого. На этапе компиляции а не рантайм.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
 class  A {};
 class  B  extends  A{};
 class  C {};

...
B b =  new  B();
C c =  new  C();
...
A a =  b; //является наследником
A a =  c; // ошибка компиляции :)
...

Пойдёт? :)
...
Рейтинг: 0 / 0
C++ & Java
    #32856060
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
NotGonnaGetUsНу зачем так грубо :) Лично я, всех программеров люблю одинаково.Извини что не заметил здесь грубости. Не могу похватстать тем что люблю всех. До Христа мне ой как далеко... Но еще раз повторюсь что и я ничего не имею против других средств разработки. Встрял я в этот разговор сугубо из НЕВЕРНЫХ суждений о шаблонах которые выдвигал Ильич. Только поэтому а не из-за того чтобы оспорить право существование Явы или чего-то другого.

NotGonnaGetUsПример Ильича как раз показывает, что можно обойтись без позднего динамического связывания введением подобных конструкций (MyCollection). Тот пример что вы привели - это не статическая проверка типов - это классический пример преобразования типов, а точнее если говорить терминами С++ (в Яве может быть и по другому) - это ЛИБО вызов кнструктора одного класса с параметрами переменной типа другого класса. ЛИБО динамическое приведение полиморфно связанных типов ПРЕДОК-ПОТОМОК, но это рановсильно dynamic_cast - это опять динамическая проверка типов. Это будет все происходить только на этапе рантайм. ПРоверено временем и программами.


NotGonnaGetUsЯ спросил какие ещё плюсы даёт С++ generic.
Я ответил в общем смысле - назвав три пункта, Потому что переход на частности - это описание языка С++.

NotGonnaGetUsЕсли всё дело только в выше описанном - не понятно зачем "генерик" ставить на один уровень с "ооп".
не знаю что такое уровень ООП, и не знаю кто его ставил шаблоны на уровень ООП. ЭТО ГЛУПО!!! дажее еще глупее. Это две разные парадигмы программирования, предназаначеные для улучшения повторного использования кода. Только эта цель их и объеденяет. В миллионный раз повторяю, что их можно использовать вместе А НЕ ЗАМЕЩАТЬ ОДНУ ДРУГОЙ. Очень хороший эффект получается от взаимного использования. Например реккурентые шаблоны. Примеры я привел выше. (заколебался повторять одно и тоже. это уже третий раз)

NotGonnaGetUsНе много не понял о чём речь. Шаблоны позволяют вместо одного стандарта сделать десять разных и потом учить им каждого нового рограммиста в проекте? Тогда стронняя библиотека тоже является расширением стандарта языка? :)
Это называется понимать слышать одно а понимать то что УДОБНО. Я как раз говорил об обратном. Скажи создание библиотек позволяет раздивнуть функциональность языка программирования? мой ответ - да. Допустим C# достаточно простой язык являющийся подмножиством С++. Ничего особо сложного и нового из себя не представляет. Польза его в том, что есть всякие WinForms, WebForms и т.д. Как VCL в Делфи. ты используешь уже готовый и отлаженный код. Никто не говорит что это ДРУГОЙ ЯЗЫК. Тебе и многим другим программистам не надо писать одно и тоже и отлаживать это.

Теперь ПОВТОРЮ ТО ЧТО БЫЛО СКАЗАНО НА ТРЕТЕЙ СТРАНИЦЕ этого ФЛЕЙМА. Потрудитесь прочитать прежде чем ерничать. Берем С++, шаблоны и пишем контейнеры. Чудно. Великолепно. все работает. Берем другой язык, там такого сделать невозможно поэтому добавляют новый тип данных - динамические массивы. Это уже расширение языка, КОТОРОЕ НЕ ПОТРЕБОВАЛОСЬ в С++. Потому что эту фичу можно реализовать имеющимися средствами.

Беру еще пример, проперти. В других языках это потребует расширения языка. В С++ написание подобного типа занимает с десяток строк и не требует принятия новых стандартнов языка.

Еще пример, чтобы вам не было лень просматривать тексты ФЛЕЙМА, посмотрите на верх этой страницы, там я привел текст класса (5 строчек), который позволяет запретить наследование того или иного класса. Опять же например в C# для этого нащдо добавлять ключевое слово. Т.е. принимать другую спецификацию языка. С++ сделано имеющимися средствами.

Еще пример, сборщики мусора, счетчики ссылок и прочее. В С++ достаточно использования умных указателей или таких ссылок как я привел выше - в начале этой странички. ОПЯТЬ ЖЕ НЕ ПРИШЛОСЬ МЕНЯТЬ ЯЗЫК.

Еще пример, делегаты. Т.е. контейнеры callback функций, а точнее функторов. Которые обильно используются в C# например, но привязаны к this того класса, на который ссылаются. В С++ можно это реализовать имеющимися средствами без принятия новых стандартов и фич языка. Причем с большими функциональными возможностями.

Другие примеры которые так сильно нервируют Ильича. Мультиметоды, анонимные методы(функции) их опять же можно (и они реализованы) средствами языка С++. Без принятия стандартов.

Вот я о чем говорил уже не раз. Очень здорово кода язык является очень гибким средством разработки позволяющим разрабатывать программы в современных условиях.


NotGonnaGetUsЯ дня три регулярно перечитывал ветку :) Просто мне показалось что вы отвечаете друг другу одно и тоже из-за не допонимания и попытлся показать в чём оно :(
ну я то точно отвечаю одно и тоже. недопонимание есть точно. тут я согласен. Это одна из черт ФЛЕЙМА. мне просто непонятно почему люди считают что некоторые преобразования типов выполняются на этапе компиляции - это не так. Тот пример, что вы приводили - он неверен. я уже об этом говорил. Это преобразование на деле будет осуществлять проверку в рантайме.
...
Рейтинг: 0 / 0
C++ & Java
    #32856062
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
NotGonnaGetUs
Код: plaintext
1.
2.
A a =  b; //является наследником
A a =  c; // ошибка компиляции :)
Пойдет?

нет. представим что у вас есть класс у которого надо определить две релизации какого-то метода, один для тех классов которым он предок, другой для остальных классов. Т.е. ошибок компиляции нет, мы просто получаем два варианта инстанцирования класса(или метода).
...
Рейтинг: 0 / 0
C++ & Java
    #32856068
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
NotGonnaGetUsОстальные проблемы решаемые шаблонами уникальны для языка С++, а не для программирования как такового.
В часностях некотрых вы правы. Но есть парочка показательных примеров. Давайте сделаем это на практике. Допустим у вас есть некая графическая среда и пока в ней реализованы только три класса Bitmap, VectorGraphics, textArea . Реализация этой среды закрыта. Ну допустим это некая внешняя программа, к который вы пишете свой плагин.

Реализуем паттерн Визитер, т.е. добавим еще одну операцию в иерархию классов, которую не можем изменить. Полчаса у меня сегодня еще есть - я подожду вашей реализации.
...
Рейтинг: 0 / 0
C++ & Java
    #32856076
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwl NotGonnaGetUsНу зачем так грубо :) Лично я, всех программеров люблю одинаково.Извини что не заметил здесь грубости. Не могу похватстать тем что люблю всех. До

...

мне просто непонятно почему люди считают что некоторые преобразования типов выполняются на этапе компиляции - это не так. Тот пример, что вы приводили - он неверен. я уже об этом говорил. Это преобразование на деле будет осуществлять проверку в рантайме.

Не переживайте вы так! Читал я третью страницу :)

В муКоллекшин каст безопасен, поскольку в вектор не может в принципе ничего попасть, кроме муОбж. С этим нужно просто смириться.
Хотя вести флейм по этому поводу у вас получается :)
...
Рейтинг: 0 / 0
C++ & Java
    #32856077
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwl NotGonnaGetUs
Код: plaintext
1.
2.
A a =  b; //является наследником
A a =  c; // ошибка компиляции :)
Пойдет?

нет. представим что у вас есть класс у которого надо определить две релизации какого-то метода, один для тех классов которым он предок, другой для остальных классов. Т.е. ошибок компиляции нет, мы просто получаем два варианта инстанцирования класса(или метода).

Можно на пальцах? Я могу вас не верно истолковать :)
Код: plaintext
1.
2.
3.
4.
сlass A {
   void method(A a) {} //для детей
   void method(Object o) {} //для остальных классов.
}
Об этом речь?
...
Рейтинг: 0 / 0
C++ & Java
    #32856080
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwl NotGonnaGetUsОстальные проблемы решаемые шаблонами уникальны для языка С++, а не для программирования как такового.
В часностях некотрых вы правы. Но есть парочка показательных примеров. Давайте сделаем это на практике. Допустим у вас есть некая графическая среда и пока в ней реализованы только три класса Bitmap, VectorGraphics, textArea . Реализация этой среды закрыта. Ну допустим это некая внешняя программа, к который вы пишете свой плагин.

Реализуем паттерн Визитер, т.е. добавим еще одну операцию в иерархию классов, которую не можем изменить. Полчаса у меня сегодня еще есть - я подожду вашей реализации.

Слишком обще поставленна задача, без наглядной иллюстрации мне с вашими терминами не разобраться.

А кто будет этой "операцией" пользоваться?
Что представляет собой плагин?
Визитёр уже реализован в "трёх классах" или нет?
...
Рейтинг: 0 / 0
C++ & Java
    #32856099
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
NotGonnaGetUsВ муКоллекшин каст безопасен, поскольку в вектор не может в принципе ничего попасть, кроме муОбж. С этим нужно просто смириться Ага и чтобы обезопасить каждый хранимый тип вам надо писать "оболочку" вокруг вектора. а попасть туда могут еще и наследники MyObj. А если вы закроете эту реализацию коллекции, тогда какой-нить другой программист поленится писать свою коллекцию и будет преобразовывать в MyObj какой-то другой класс. Или я не прав? Тогда попадать туда может черте что. Или я опять флеймю по вашему?

NotGonnaGetUsМожно на пальцах? Я могу вас не верно истолковать :) можно. Фишка в том, что опять надо писать меньше кода. Вам так придется добавлять методы для каждого типа аргументов. Иногда это нереально. несколько примеров. Пример типизированный буффер. Ему могут передаваться типы для которых проканает обычное бинарное копирование, а могут передаваться и те для которых это не верно. Получется приблизительно такая картина.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
template<T>
struct isCopiable{
  enum { value = typelist::indexOf<PrimitiveTypes, const T>::value >  0  };
};

template<T>
struct isCopiable<T*>{
  enum { value = true };
};

template<int v>
struct Int2Type{
  enum{ value = v };
};

template<T>
class buffer{
  enum{ Copiable = isCopybale<T>::value !=  0  };

  // далее два метода которые покрывает ВСЕ ситуации
  // для любого типа буфферной переменной
  void Init( size_t n, const T& value, Int2Type<false> )
  {
    ....
  }

  void Init( size_t n, const T& value, Int2Type<true> )
  {
   ...
  }
public:
  explicit buffer( size_t n, const T& value = T() )
  {
    Init( n, value, Int2Type<Copiable> );
  }
}

прием достаточно просто, при подстановке типа скомпилируется только нужный в данной ситации метод. Нам не надо переписывать интерфейс этого класса для всех типов которые могут встретиться. Понимаешь? Вот еще примерчик
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
// допустим есть некий контейнер, членами которго могут быть как полиморфные типы так и нет
// нам надо иметь методы как для полиморфных, так и других типов
template<class T, bool isPolymorphic>
class Container
{
private:
  void DoSomething(T* pObj, Int2Type<true>)
  {
    T* temp = pObj->Clone();
    ....
  }

  void DoSomething(T* pObj, Int2Type<false>)
  {
    T* temp = new T(*pObj);
    ....
  }
public:
  void DoSomething(T* pObj)
  {
     DoSomething( pObj, Int2Type<isPolymorphic> );
  }
}
опять для каждого из классов которые будут передаваться шаблону, будет генерироваться нужный ему метод вызова. Идея понятна? Мы управляем процессом компиляции, это как RTTI только в статике. Инкапсулируя реализацию в шаблонные методы или классы мы можем сделать программу независящей от того какой тип используется. Более того мы можем использовать особенности того или иного типа, компилятор подставит нужную реализацию метода. Или создаст нудный метод или тип.

NotGonnaGetUsСлишком обще поставленна задача, без наглядной иллюстрации мне с вашими терминами не разобраться.

А кто будет этой "операцией" пользоваться?
Что представляет собой плагин?
Визитёр уже реализован в "трёх классах" или нет?
простите, я думал вы знаете что такое паттерн проектирования Визитер. Задача показалась вам общей. Вы смотрите совсем не на те условия. Я не злобный препод который стремится поставить в любом случае вам плохую оценку.

Основную суть я сказал. Повторю. Есть три класса Bitmap, VectorGraphics, textArea . Вы не можете менять их реализацию и структуру этих классов. Но вам позарез надо добавить еще одну функуиональность, например сохранение объектов этих классов в XML. В этих случаях, когда надо добавить функциональность во всю иерархию классов, а она закрыта (нельзя определить в базовом классе виртуальный метод), используется паттерн Визитер. Пусть доупстим это будет некая функция или метод класса, котору передается экземпляр этой иерархии и нудно для каждого реализовать что свое. Забыл самое главное - базовый класс этой закрытой иерархии Graphics. Таких условий достаточно?

реализацию самой функции мне не надо главное суть. что-то вроде этого
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
void SomeOperation(Graphics* p)
{
    if (TextArea* pTextArea = dynamic_cast<TextArea*>(p))
    {
        ... делаем что-то для TextArea ...
    }
    else if (VectorGraphics* pVectorGraphics =
        dynamic_cast<VectorGraphics*>(p))
    {
        ... VectorGraphics ...
    }
    else if (Bitmap* pBitmap = dynamic_cast<Bitmap*>(p))
    {
        ... Bitmap ...
    }
    else
    {
        throw "Unknown type passed";
    }
}
согласны с такой реализацией? что вы можете к этому добавить? какие в этой реализации недостатки? какие возможны улучшения? Завтра посмотрю на вашу реализацию и покажу как можно сделать при помощи шаблонов - пока!
...
Рейтинг: 0 / 0
25 сообщений из 160, страница 4 из 7
Форумы / C++ [игнор отключен] [закрыт для гостей] / C++ & Java
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]