| 
			| 
					
						| CTAPOBEP | 
								|  | «  : 12-08-2008 10:15 »  |  | 
 
 Первое. Шаблон класса. template <class TYPE>class New
 {
 TYPE m_pType;
 
 public:
 New(void) {m_pType=NULL;}
 New(unsigned int num) {m_pType=(TYPE)new char [sizeof(TYPE)*num];}
 New(TYPE arg) {*this=arg;}
 ~New(void) {if (m_pType) delete [] m_pType;}
 TYPE operator= (TYPE arg)
 {
 if (m_pType) delete [] m_pType;
 return m_pType=arg;
 }
 operator TYPE() {return m_pType;}
 TYPE operator->() {return m_pType;}
 };
 
Второе. Как этим пользоваться. Вместо char* ch=new char[num];
 пишем
 
 New <char*> ch=new char [num]; //или New <char*> ch(num);
 
 а дальше - все, как обычно:
 
 strcpy(ch, "ABCDEFGH");
 ch[8]=0x00;
 
 или
 
 ch="HGFEDCBA\n";
 
 или
 
 ch[0]='A';
 ch[1]='B';
 ...
 ch[8]='\0'
 
 if (strcmp(ch, "Abc")) ...
 
 ну и т.д.
 
 Вместо delete [] ch; не пишем ничего, само удалится.
 
Третье. Все это хорошо, но совсем не интересно. Интересно вот что.  class CTestDlg{
 New <CButton*> m_Button[50]; // Это вместо CButton* m_Button[50];
 ...
 
 
 BOOL CTestDlg::OnInitDialog()
 {
 ...
 for (int i=0; i<50; i++)
 {
 m_Button[i]=new CButton;
 RECT rect={20, 20+i*60, 200, 20+i*60+50};
 m_Button[i]->Create("Кнопка", WS_VISIBLE|WS_CHILD, rect, this, 1000+i);
 }
 ...
 }
 
 void CTestDlg::OnDestroy()
 {
 // Теперь это не нужно !!!
 // for (int i=0; i<50; i++) delete m_Button[i];
 }
 
Четвертое. Вопрос. Посмотрите свежим глазом, какие могут быть проблемы при использовании такого класса? Спасибо за внимание. |  
						| 
								|  |  
								| « Последнее редактирование: 12-08-2008 11:36 от CTAPOBEP » |  Записан | 
 |  |  | 
	| 
			| 
					
						| RXL | 
								|  | « Ответ #1 : 12-08-2008 10:40 »  |  | 
 
 CTAPOBEP, оберни код тегами [code]...[/code]. |  
						| 
								|  |  
								|  |  Записан | 
 
 ... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С. |  |  | 
	| 
			| 
					
						| Finch 
								СпокойныйАдминистратор    Offline 
								Пол:    
								Пролетал мимо
								
								
								
								
								
							 | 
								|  | « Ответ #2 : 12-08-2008 12:10 »  |  | 
 
 Смотри в нете шаблон "Умные указатели". Тест:
 ch="HGFEDCBA\n"; Тест не прошел Программа на выполнении упала.
 printf("%s", ch); Тест не прошел Программа на выполнении упала.
 ch[0]='a'; Тест не прошел. Программа на выполнении упала.
 Еше, может быть ситуация, что два разных указателя ссылаются на один и тот же участок памяти. При удалении одного указателя, Второй у тебя станет не валидным. Что приведет к краху программы.
 
 Если интересно, я могу вечером выложить свой велосипед на эту тему.
 |  
						| 
								|  |  
								| « Последнее редактирование: 12-08-2008 12:13 от Finch » |  Записан | 
 
 Не будите спашяго дракона.              Джаффар (Коша) |  |  | 
	| 
			| 
					
						| CTAPOBEP | 
								|  | « Ответ #3 :  12-08-2008 12:52 »   |  | 
 
 ch="HGFEDCBA\n"; Тест не прошел Программа на выполнении упала. printf("%s", ch); Тест не прошел Программа на выполнении упала. ch[0]='a'; Тест не прошел. Программа на выполнении упала. Странно, а у меня все это работает и выдает именно тот результат, какой должен быть. MSVS 6.0 + MFC. Велосипед выкладывай, я люблю велосипеды   |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| Алексей++ 
								глобальный и пушистыйГлобальный модератор    Offline 
								Сообщений: 13
								
								
								
								
								
							 | 
								|  | « Ответ #4 : 12-08-2008 16:37 »  |  | 
 
 Странно, а у меня все это работает и выдает именно тот результат, какой должен быть. 
 ты, случаем, не в ДОСе выполняешь ?   |  
						| 
								|  |  
								|  |  Записан | 
 
 |  |  | 
	| 
			| 
					
						| Finch 
								СпокойныйАдминистратор    Offline 
								Пол:    
								Пролетал мимо
								
								
								
								
								
							 | 
								|  | « Ответ #5 : 12-08-2008 18:48 »  |  | 
 
 Вот мой велосипед.  #include <assert.h>#include <iostream>
 
 template <class T>
 class smart_ptr
 {
 private:
 struct Tptr
 {
 int count;
 T *ptr;
 Tptr()
 {
 count=1;
 ptr=NULL;
 }
 };
 
 Tptr * ptr;
 
 void delete_ptr()
 {
 if (ptr != NULL)
 {
 ptr->count--;
 if (ptr->count == 0)
 {
 delete ptr->ptr;
 delete ptr;
 }
 ptr=NULL;
 }
 };
 
 void new_ptr(T *t)
 {
 delete_ptr();
 ptr=new Tptr;
 if (ptr != NULL) ptr->ptr=t;
 };
 
 void inc_ptr(Tptr *t)
 {
 delete_ptr();
 ptr=t;
 if (ptr != NULL) ptr->count++;
 }
 
 public:
 smart_ptr() {ptr=NULL;};
 smart_ptr(T *t)
 {
 ptr=NULL;
 new_ptr(t);
 };
 
 smart_ptr(const smart_ptr<T> & cl)
 {
 ptr=NULL;
 inc_ptr(cl.ptr);
 };
 
 ~smart_ptr()
 {
 delete_ptr();
 };
 
 smart_ptr & operator = (T *t)
 {
 if (t != NULL)
 {
 new_ptr(t);
 }
 return *this;
 };
 
 smart_ptr & operator = (smart_ptr<T> & cl)
 {
 inc_ptr(cl.ptr);
 return *this;
 };
 
 T& operator *()
 {
 assert(ptr != NULL);
 assert(ptr->ptr != NULL);
 return *ptr->ptr;
 
 };
 
 T *operator ->()
 {
 assert(ptr != NULL);
 assert(ptr->ptr != NULL);
 return ptr->ptr;
 };
 
 T *& get()
 {
 assert(ptr != NULL);
 assert(ptr->ptr != NULL);
 return ptr->ptr;
 };
 
 };
 
 int main()
 {
 smart_ptr<int> a(new int), b;
 *a = 123;
 std::cout << "*a.get() = " << *a << std::endl;
 b=a;
 if (a.get() == NULL)
 std::cout << "As result a.get() is NULL." << std::endl;
 std::cout << "*b.get() = " << *b.get() << std::endl;
 return 0;
 
 }
 [/quote]
 Делал для своих нужд, поэтому особой функциональности прошу не ожидать :)
 |  
						| 
								|  |  
								|  |  Записан | 
 
 Не будите спашяго дракона.              Джаффар (Коша) |  |  | 
	| 
			| 
					
						| CTAPOBEP | 
								|  | « Ответ #6 : 13-08-2008 04:30 »  |  | 
 
 "ты, случаем, не в ДОСе выполняешь ?"  А что это такое ?   Вот кусок кода, который у меня прекрасно работает: BOOL CTestDlg::OnInitDialog(){
 CDialog::OnInitDialog();
 
 // Set the icon for this dialog.  The framework does this automatically
 //  when the application's main window is not a dialog
 SetIcon(m_hIcon, TRUE);			// Set big icon
 SetIcon(m_hIcon, FALSE);		// Set small icon
 
 
 New <char*> ch=new char [9];
 strcpy(ch, "ABCDEFGH");
 ch[8]=0x00;
 
 AfxMessageBox(ch);
 
 ch="HGFEDCBA\0";
 AfxMessageBox(ch);
 
 ch[0]='a';
 ch[1]='b';
 ch[2]='c';
 ch[3]='d';
 ch[4]='e';
 ch[5]='f';
 ch[6]='g';
 ch[7]='h';
 ch[8]='\0';
 
 AfxMessageBox(ch);
 
 if (!strcmp(ch, "abcdefgh")) AfxMessageBox("Равно !!!");
 else AfxMessageBox("Не равно !!!");
 
 return TRUE;  // return TRUE  unless you set the focus to a control
 }
 
Finch, спасибо, есть куда расти   Так. Почему меня так мало пинают? Ну вот как в таких условиях код улучшать? |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| Finch 
								СпокойныйАдминистратор    Offline 
								Пол:    
								Пролетал мимо
								
								
								
								
								
							 | 
								|  | « Ответ #7 : 13-08-2008 10:51 »  |  | 
 
 CTAPOBEP, Может ты не привел полностью код. Но конструкция ch[0]='a'; у тебя явно должна не работать. Так как, ты по крайней мере не переопредели []. У меня стоит компилятор g++ (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21). И на нем при компиляции выскакивают warning. При исполнении программа просто падает. |  
						| 
								|  |  
								|  |  Записан | 
 
 Не будите спашяго дракона.              Джаффар (Коша) |  |  | 
	| 
			| 
					
						| Алексей++ 
								глобальный и пушистыйГлобальный модератор    Offline 
								Сообщений: 13
								
								
								
								
								
							 | 
								|  | « Ответ #8 : 13-08-2008 18:01 »  |  | 
 
 CTAPOBEP, DOS я имею в виду ) |  
						| 
								|  |  
								|  |  Записан | 
 
 |  |  | 
	| 
			| 
					
						| CTAPOBEP | 
								|  | « Ответ #9 : 14-08-2008 04:39 »  |  | 
 
 Я привел тот код, который сам добавил, все остальное - дело рук Wizard'a. Вот проект целиком, желающие могут убедиться - http://slil.ru/26057820 По поводу непереопределенного оператора [] - есть оператор TYPE, от возвращает указатель, этого должно быть достаточно. "CTAPOBEP, DOS я имею в виду )" А я имею в виду, что даже слова такого не знаю   |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| Антон (LogRus) | 
								|  | « Ответ #10 : 14-08-2008 05:28 »  |  | 
 
 поправил код ибо не айс: template <class T> // че-то не люблю я стиль аля VS 6.0class another_smart_ptr // суть класса
 {
 T * pointer_; // так оно надёжней, представь инстанцирование простым интом
 
 public:
 another_smart_ptr() : pointer_(NULL) {} // пишем на C++
 another_smart_ptr(unsigned int num): pointer_(NULL) { pointer_ = new T [num]; }
 another_smart_ptr(T * arg) { *this = arg; }
 ~another_smart_ptr(void) {if (pointer_) delete [] pointer_;}
 T* operator= (T * arg)
 {
 if (pointer_) delete [] pointer_;
 return pointer_ = arg;
 }
 operator T*() { return pointer_; } // не очень здорово, слишком не явно
 operator const T*() const { return pointer_; } // иначе будут грабли в некоторых ситуациях
 T* operator->() { return pointer_; }
 };
 
 
 int _tmain(int argc, _TCHAR* argv[])
 {
 
 another_smart_ptr<char> ch = new char[9];
 
 // strcpy(ch, "ABCDEFGH\0"); это хрень " подразумевает завершающий ноль
 strcpy(ch, "ABCDEFGH\0");
 // ch[8]=0x00; и нафига мы его еще раз проставили
 
 //ch = "HGFEDCBA"; а это самое интерестное
 // подумаем, что тут происходит
 // тут мы берём и копируем указатель на ВРЕМЕННЫЙ КОНСТАНТНЫЙ ЛОКАЛЬНЫЙ объект
 // и нам это удаётся :), но компилятор сам решает: где, когда и как
 // он хранит, создаёт и удаляет объект
 // у нас есть одна гарантия он доступен пока не завершится operator=
 strcpy(ch, "HGFEDCBA");
 
 // ну то что его может в любом месте разорвать является следствием
 // копирования указателя на константу
 ch[0]='a';
 ch[1]='b';
 ch[2]='c';
 ch[3]='d';
 ch[4]='e';
 ch[5]='f';
 ch[6]='g';
 ch[7]='h';
 ch[8]='\0';
 
 std::cout << strcmp(ch, "abcdefgh");
 
 return 0;
 }
 
 |  
						| 
								|  |  
								|  |  Записан | 
 
 Странно всё это.... |  |  | 
	| 
			| 
					
						| CTAPOBEP | 
								|  | « Ответ #11 : 14-08-2008 07:16 »  |  | 
 
 "тут мы берём и копируем указатель на ВРЕМЕННЫЙ КОНСТАНТНЫЙ ЛОКАЛЬНЫЙ объект"
 
 Согласен, так делать не следует. И вообще - не следует смешивать между собой указатели, объявленные обычным образом и объекты подобного класса.
 
 |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| Антон (LogRus) | 
								|  | « Ответ #12 : 14-08-2008 08:21 »  |  | 
 
 CTAPOBEP, честно говоря этот класс кроме, как из праздного любопытства вообще не следовало писать.есть же
 std::string
 std::vector<char>
 std::auto_ptr
 std::rope
 boost::scoped_ptr
 boost::scoped_array
 boost::shared_ptr
 boost::shared_array
 
 для чего он нужен?
 вот честно что он даёт?
 для чего использовался?
 |  
						| 
								|  |  
								|  |  Записан | 
 
 Странно всё это.... |  |  | 
	| 
			| 
					
						| Антон (LogRus) | 
								|  | « Ответ #13 : 14-08-2008 08:46 »  |  | 
 
 совсем забыл.Еще же есть boost pointer containers
 работаешь как с вектором, а реально хранишь указатели красота
 
 кстати вопрос, то был, какие проблемы
 что, то я в коде уже отметил
 в основном это не явное поведение класса
 оператор равно делает не, то что ожидаем (лучше reset)
 не метода передачи владения release
 константные методы не реализованы
 нет оператора приведения к bool
 оператор неявного приведения к *, как не кажется не слишком удачное решение в плане прозрачности восприятия
 
 в общем мне больше по душе интерфейс scoped_prt/shared_prt/auto_ptr
 
 |  
						| 
								|  |  
								| « Последнее редактирование: 14-08-2008 08:53 от LogRus » |  Записан | 
 
 Странно всё это.... |  |  | 
	| 
			| 
					
						| CTAPOBEP | 
								|  | « Ответ #14 : 14-08-2008 12:10 »  |  | 
 
 "кроме, как из праздного любопытства вообще не следовало писать" Герберт Шилдт с тобой определенно не согласен     В своей книге "Искусство программирования на С++" он рассматривает целых два варианта подобного класса (и еще немножко касается теории этого вопроса). За информацию - спасибо, беру на заметку. |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| Антон (LogRus) | 
								|  | « Ответ #15 : 15-08-2008 07:17 »  |  | 
 
 Это не он со мной не согласен, это я с ним не согласен.   Не будем спорить о полезности изобретения велосипедов    каждый проект уникален и требует индивидуального подхода. |  
						| 
								|  |  
								|  |  Записан | 
 
 Странно всё это.... |  |  | 
	|  |