class PNList
{
public:
PNList(PNList *pr,void *el);
void *elem;//ТУТ ВОПРОС
int number;
~PNList();
PNList *Prev;
PNList *Next;
};
PNList::PNList(PNList *pr,void *el)
{
Next=NULL;
Prev=pr;
elem=el;
};
PNList::~PNList()
{
Prev->Next=Next;
Next->Prev=Prev;
};
_________________________________
class IntElem
{
public:
IntElem();
int el;
int out();
~IntElem();
};
IntElem::IntElem()
{
el=11;
};
int IntElem::out()
{
std::cout<<el<number=10;
List->Elem //КАК ИСПОЛЬЗОВАТЬ МЕТОД OUT КЛАССА INTELEM? То-есть elem должен сам себя показать
...
return 0;
};
Другие языки программирования и технологии
C++. Вопрос
В C++ существует специальный тип указателя, который называется указателем на неопределённый тип. Для определения такого указателя вместо имени типа используется ключевое слово void в сочетании с описателем, перед которым располагается символ ptrОперации *.
void * UndefPoint;
С одной стороны, объявленная подобным образом переменная также является объектом определённого типа - типа указатель на объект неопределённого типа.
Но, с другой стороны, для объекта типа указатель на объект неопределённого типа отсутствует информация о размерах и внутренней структуре адресуемого участка памяти. Из-за этого не могут быть определены какие-либо операции для преобразования значений
Поэтому переменной UndefPoint невозможно присвоить никаких значений без явного преобразования этих значений к определённому типу указателя
UndefPoint = 0xb8000000; // Такое присвоение недопустимо
Подобный запрет является вынужденной мерой предосторожности. Если разрешить такое присвоение, то неизвестно, как поступать в случае, когда потребуется изменить значение переменной UndefPoint, например, с помощью операции инкремента
UndefPoint++; // Для типа void * нет такой операции
Эта операция (как и любая другая для типа указатель на объект неопределённого типа) не определена. И для того, чтобы не разбираться со всеми операциями по отдельности, лучше пресечь подобные недоразумения "в корне", то есть на стадии присвоения значения
Объектам типа указатель на объект неопределённого типа в качестве значений разрешается присваивать значения лишь в сочетании с операцией явного преобразования типа
В этом случае указатель на объект неопределённого типа становится обычным указателем на объект какого-либо конкретного типа. Со всеми вытекающими отсюда последствиями
Но и тогда надо постоянно напоминать транслятору о том типе данных, который в данный момент представляется указателем на объект неопределённого типа:
int m = 10;
pUndefPointer = (int *) &m;
pUndefPointer выступает в роли указателя на объект типа int
(*(int *) pUndefPointer)++;
Для указателя на объект неопределённого типа не существует способа непосредственной перенастройки указателя на следующий объект с помощью операции инкрементации. В операторе, реализующем операции инкрементации и декрементации, только с помощью операций явного преобразования типа можно сообщить транслятору величину, на которую требуется изменить первоначальное значение указателя
pUndefPointer++; // Это неверно, инкремент не определён
(int *) pUndefPointer++; // И так тоже ничего не получается
((int *) pUndefPointer)++; // А так хорошо… Сколько скобок!
++(int *) pUndefPointer; // И вот так тоже хорошо
С помощью операции разыменования и с дополнительной операцией явного преобразования типа изменили значение переменной m
pUndefPointer = (int *) pUndefPointer + sizeof(int);
Теперь перенастроили указатель на следующий объект типа int
pUndefPointer = (int *) pUndefPointer + 1;
И получаем тот же самый результат
Специфика указателя на объект неопределённого типа позволяет выполнять достаточно нетривиальные преобразования:
(*(char *) pUndefPointer)++;
А как изменится значение переменной m в этом случае?
pUndefPointer = (char *) pUndefPointer + 1;
Указатель перенастроился на объект типа char. То есть просто сдвинулся на 1байт
Работа с указателями на объекты определённого типа не требует такого педантичного напоминания о типе объектов, на которые настроен указатель. Транслятор об этом не забывает
int * pInt;
int m = 10;
pInt = &m; // Настроили указатель
pInt++; // Перешли к очередному объекту
*pInt++; // Изменили значение объекта, идущего следом за переменной m
Операции явного преобразования типов позволяют присваивать указателям в качестве значений адреса объектов типов, отличных от того типа объектов, для которого был объявлен указатель:
int m = 10;
char c = 'X';
float f = 123.45;
pInt = &m;
pNullInt = (int *) &c;
pNullInt = (int *) &f; // Здесь будет выдано предупреждение об опасном преобразовании
void * UndefPoint;
С одной стороны, объявленная подобным образом переменная также является объектом определённого типа - типа указатель на объект неопределённого типа.
Но, с другой стороны, для объекта типа указатель на объект неопределённого типа отсутствует информация о размерах и внутренней структуре адресуемого участка памяти. Из-за этого не могут быть определены какие-либо операции для преобразования значений
Поэтому переменной UndefPoint невозможно присвоить никаких значений без явного преобразования этих значений к определённому типу указателя
UndefPoint = 0xb8000000; // Такое присвоение недопустимо
Подобный запрет является вынужденной мерой предосторожности. Если разрешить такое присвоение, то неизвестно, как поступать в случае, когда потребуется изменить значение переменной UndefPoint, например, с помощью операции инкремента
UndefPoint++; // Для типа void * нет такой операции
Эта операция (как и любая другая для типа указатель на объект неопределённого типа) не определена. И для того, чтобы не разбираться со всеми операциями по отдельности, лучше пресечь подобные недоразумения "в корне", то есть на стадии присвоения значения
Объектам типа указатель на объект неопределённого типа в качестве значений разрешается присваивать значения лишь в сочетании с операцией явного преобразования типа
В этом случае указатель на объект неопределённого типа становится обычным указателем на объект какого-либо конкретного типа. Со всеми вытекающими отсюда последствиями
Но и тогда надо постоянно напоминать транслятору о том типе данных, который в данный момент представляется указателем на объект неопределённого типа:
int m = 10;
pUndefPointer = (int *) &m;
pUndefPointer выступает в роли указателя на объект типа int
(*(int *) pUndefPointer)++;
Для указателя на объект неопределённого типа не существует способа непосредственной перенастройки указателя на следующий объект с помощью операции инкрементации. В операторе, реализующем операции инкрементации и декрементации, только с помощью операций явного преобразования типа можно сообщить транслятору величину, на которую требуется изменить первоначальное значение указателя
pUndefPointer++; // Это неверно, инкремент не определён
(int *) pUndefPointer++; // И так тоже ничего не получается
((int *) pUndefPointer)++; // А так хорошо… Сколько скобок!
++(int *) pUndefPointer; // И вот так тоже хорошо
С помощью операции разыменования и с дополнительной операцией явного преобразования типа изменили значение переменной m
pUndefPointer = (int *) pUndefPointer + sizeof(int);
Теперь перенастроили указатель на следующий объект типа int
pUndefPointer = (int *) pUndefPointer + 1;
И получаем тот же самый результат
Специфика указателя на объект неопределённого типа позволяет выполнять достаточно нетривиальные преобразования:
(*(char *) pUndefPointer)++;
А как изменится значение переменной m в этом случае?
pUndefPointer = (char *) pUndefPointer + 1;
Указатель перенастроился на объект типа char. То есть просто сдвинулся на 1байт
Работа с указателями на объекты определённого типа не требует такого педантичного напоминания о типе объектов, на которые настроен указатель. Транслятор об этом не забывает
int * pInt;
int m = 10;
pInt = &m; // Настроили указатель
pInt++; // Перешли к очередному объекту
*pInt++; // Изменили значение объекта, идущего следом за переменной m
Операции явного преобразования типов позволяют присваивать указателям в качестве значений адреса объектов типов, отличных от того типа объектов, для которого был объявлен указатель:
int m = 10;
char c = 'X';
float f = 123.45;
pInt = &m;
pNullInt = (int *) &c;
pNullInt = (int *) &f; // Здесь будет выдано предупреждение об опасном преобразовании
ой ёёё..
Похожие вопросы
- вопрос про массив одномерный C++ (вопрос отредактирован)
- C++ Вопросы
- C++. Вопрос для разбирающихся.
- C++. Вопрос по функции memmove()
- C++ вопрос по cin&cout, правильное использование
- Ещё тупой вопрос по C++ :)
- Вопрос актуальности языка C++, расхождение источников. Мне нужна достоверная инфа на это счет.
- Вопрос для тех кто знает точный ответ, язык C про функции все подробности вопроса внутри...
- Вопрос по трассировке цикла со вложенностью. C++
- Особенности арифметических операций в C++, деление отрицательных чисел, вопрос ниже
КАК ОРГАНИЗОВАТЬ ПРАВИЛЬНО?
class IntElem
{
public:
IntElem();
int el;
int out();
~IntElem();
};
IntElem::IntElem()
{
el=11;
};
int IntElem::out()
{
std::coutnumber=10;
List->Elem //КАК ЗДЕСЬ СДЕЛАТЬ, ЧТОБЫ ELEM ПОКАЗАЛ САМ СЕБЯ?
...
return 0;
}
{
public:
PNList(PNList *pr,void *el);
void *elem;
int number;
~PNList();
PNList *Prev;
PNList *Next;
};
PNList::PNList(PNList *pr,void *el)
{
Next=NULL;
Prev=pr;
elem=el;
};
PNList::~PNList()
{
Prev->Next=Next;
Next->Prev=Prev;
};