Предыдущий пост -
Следующий пост -

Класс Ptr_to_T.

Рубрика: C++, Дата: 25 March, 2013, Автор:
Tags:

Завершите класс Ptr_to_T из параграфа 11.11 и протестируйте его. По крайней мере определите для этого класса операции *, ->, =, ++ и –. Сделайте так, чтобы ошибка времени выполнения возникала, только при разыменовании недействительных ссылок.

Нам еще дан код самого класса Ptr_to_T вот он:

class Ptr_to_t
{
	T* p;
	T* array;
	int size;
	
public:
	Ptr_to_T(T* p, T* v, int s);//priv9zka k maccivy v razmera s; nach. znachenie p
	Ptr_to_T(T* p);//priv9zka k ob6ekty; nachal6noe znachenie p
	
	Ptr_to_T& operator++();//prefikcnui
	Ptr_to_T operator++(int);//poctfikcnui
	
	Ptr_to_T& operator--();//prefikcnui
	Ptr_to_T operator--(int);//poctfikcnui
	
	T& operator* ();//prefikcna9 operaci9
};

Как мы видим в нем ничего нет. Здесь имеется ввиду делать для шаблона, там в параграфе говорится, что это будет следующая задача которая в главе 14, поэтому мы пока, что попытаемся составить наш класс для конкретного указателя например для int* или char*. Я еще пока не решил для каких указателей буду его составлять.

Этот класс вообще называется интеллектуальными указателями, я наверно мб пожже пост создам на тему интеллектуальные указатели, хотя хз как пойдет.

Ну вообщем тут конечно есть для меня проблемы, например я ни разу не перегружал операцию -> и * хз как пойдет. Ладно полно трепаться начинаем решать. Да пойдем по порядку начнем с того, что знаем, например с конструкторов.

Да пока я не сильно понимаю еще так сказать указатели, от посмотрите на конструктор Ptr_to_T(T* p, T* v, int s); три параметра передается. Первый это как бы указатель, второй это указатель на массив, а третий это сам размер массива. Интересно? Правда ж? Чем же отличается указатель, от указателя на массив. Почему нельзя просто передать один указатель? Да вопросы конечно у меня появились и именно по языку, это так можно сказать азы которые каждый С++ программист должен знать. Хорошо будем разбираться поехали. Как говориться новенькое для себя открою щас. Поехали.

Херню я конечно набросал пока, непонятно конечно, чото для типа int* никаких ошибок не выбрасывает если мы int *p делаем ++ и дальше присваиваем я так смотрю для int

Вот я токо хотел вопрос задать на форуме но тут как раз кода я его писал у меня ответ возник сам собой. Вот сам вопрос и рассуждения.

Здорова!
Пытаюсь создать класс для интеллектуальных указателей для указателей типа int* пока, но ничо не получается.

как бы есть класс:

<strong>class Ptr_to_t</strong>
<strong>{</strong>
<strong>    int* p;</strong>
<strong>    int* array;</strong>
<strong>    int size;</strong>
     
<strong>public:</strong>
<strong>    Ptr_to_T(int* p, int* v, int s):p(p),v(v),s(s){};//priv9zka k maccivy v razmera s; nach. znachenie p</strong>
<strong>    Ptr_to_T(int* p):p(p){};//priv9zka k ob6ekty; nachal6noe znachenie p</strong>
     
<strong>    Ptr_to_T&amp; operator++();//prefikcnui</strong>
<strong>    Ptr_to_T operator++(int);//poctfikcnui</strong>
     
<strong>    Ptr_to_T&amp; operator--();//prefikcnui</strong>
<strong>    Ptr_to_T operator--(int);//poctfikcnui</strong>
<strong>   {</strong>
<strong>      return p--;</strong>
<strong>   }</strong>
     
<strong>    int&amp; operator* ();//prefikcna9 operaci9</strong>
<strong>   {</strong>
<strong>return *p;</strong>
<strong>}</strong>
<strong>};</strong>

и у меня не получается вызвать ошибку run-time error.
от например код в примере из книги

<strong>int v[200]={0};</strong>
<strong>Ptr_to_T p(&amp;v,v,200);</strong>
<strong>p--;</strong>
<strong>*p=30; //отут должна быть ошибка времени выполнения но чото ее нету.</strong>

в функции operator–(int) я естественно вывел и посмотрел, что у меня выходит при –p, и увидел, что указатель указывает на какое то число на целое, например такое 13432412 – это после p–, а если сразу cout <<p, то выводит 0, тоесть как бы стоит на начале массива.

Это вообще задачка из книги, там нужно написать класс который будет имитировать указатели, токо будет обрабатываться ошибки выхода из диапазона потому, что в обычных указателях не обрабатываются. А у меня я смотрю тоже ничо не обрабатывается  или как то мне нужно проверку сделать, я от чото еще не пойму зачем нам еще нужно int array и int size? мб их как то нужно использовать? хз

Вообще я с указателями не сильно знаком но глядя на их поведения, я так смотрю у них нету выхода ошибки нету, хоть мы — делаем раз 300 хоть ++ 300 раз, все рамно в какую то ячейку памяти попадаем. Ну если  действительно так оно и есть, то тут идея прикольная возникла мб просто проверять значение которое будет  при p– некоректное и сравнивать со значениями в массиве array а затем уже заменять его, а хотя я тупанул, а бля тупанул массив это адреса, а размер количество адресов. Если адрес не попадает в диапазон адресов массива array, то нужно генерировать исключение. Ну вообщем все ясно стало. Щас попробуем.

Все замучил я ее. Даю вам код. Файл Ptr_to_T.h:

//ob69vlenie klacca Ptr_to_t
#ifndef PTR_TO_T_H
#define PTR_TO_T_H

class Ptr_to_T
{
	int* p;//ykazatel6 na tekychii element
	int* array;//ykazatel6 na macciv
	int size;//razmer macciva
	
public:
	class Run_time_error {};
	//konctryktor preobrazovani9
	Ptr_to_T(int*p, int* v, int s);//priv9zka k maccivy v razmera s; nach. znachenie p
	
	//xz zachem on nyjen
	Ptr_to_T(int* p);//priv9zka k ob6ekty; nachal6noe znachenie p
	
	
	Ptr_to_T& operator++();//prefikcnui
	Ptr_to_T operator++(int);//poctfikcnui
	
	Ptr_to_T& operator--();//prefikcnui
	Ptr_to_T operator--(int);//poctfikcnui
	
	//razumenovanie
	int& operator* ();//prefikcna9 operaci9
};

#endif

файл Ptr_to_T.cpp:

//opredelenie Ptr_to_T

#include "Ptr_to_T.h"

//konctryktor preobrazovani9
Ptr_to_T::Ptr_to_T(int*p, int* v, int s)//priv9zka k maccivy v razmera s; nach. znachenie p
:p(p),array(v),size(s){}

//konctrykotr preobrazovani9 xz zachem on nyjen
Ptr_to_T::Ptr_to_T(int* p)//priv9zka k ob6ekty; nachal6noe znachenie p
:p(p){}

Ptr_to_T& Ptr_to_T::operator++()//prefikcnui
{
	++p;
	return *this;
}

Ptr_to_T Ptr_to_T::operator++(int)//poctfikcnui
{
	return p++;
}

Ptr_to_T& Ptr_to_T::operator--()//prefikcnui
{
	p--;
	return *this;
}

Ptr_to_T Ptr_to_T::operator--(int)//poctfikcnui
{
	cout <<*p<<endl;
	Ptr_to_T b(p--,array,size);
	cout <<*p<<endl;
	return b;
}

//razumenovanie
int& Ptr_to_T::operator* ()//prefikcna9 operaci9
{
	int flag=0;
	for(int i=0;i<size;i++)
	{
		if(&array[i]==p)
		{
			flag=1;
		}
	}
	
	if(flag==0)
		throw Run_time_error();

	return *p;
}

и main.cpp:

//ykazatel6 na massiv i ykazatel6 cculka na macciv
#include <iostream>
using std::cout;
using std::endl;

int main()
{
	int *mass, *p, a[30];
	
	for(int i=0;i<30;i++)
		a[i]=i;
	cout <<a[1]<<endl;
	mass=a;
	p=&a[0];
	cout <<*p<<endl;
	cout <<*mass<<endl;
	p--;
	for(int i=0;i<30;i++)
		if(&mass[i]==p)
			cout <<"ect6"<<endl;
	
	return 0;
}

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

А что еще сказать зато решили вопросы по поводу того чем отличается указатель на массив от указателя на элемент массива. Да и вообще глобальное понятие указателей и выход за пределы хоть удалось как то понять, например я всегда думал, что ошибка получается когда есть массив и когда создается указатель как в примере минусовой, а на практике нифига все по тихому. Ну да ладно. Будем знать терь.

Да еще добавлю присвоение от если у нас есть массив int v[30]; допустим, и есть два указателя int *p, *array; это так  на вскидку прикинем. То что мы можем сделать? Допустим мы присвоим p=&v[0]; первый элемент массива, а array=v; весь массив. Что у нас будет в p как вы думаете? Правильно адрес первого елемента. а как вы думаете, что будет в array[0]? Значение первого элемента, а как нам получить в массиве адрес первого элемента? Да просто &array[0]; и это будет адрес первого элемента.

Вообщем запутано все конечно для восприятия тяжело. Ну ясно, но всеже тяжеловато.

 

rss