PureBasic - форум

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Как правильно сделать простой конструктор объектов?


Как правильно сделать простой конструктор объектов?

Сообщений 1 страница 8 из 8

1

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

0

2

Код:
Structure Person
  Name$
  Age.l
  List Friends$()
EndStructure

Procedure Create()
  *mem = AllocateMemory(SizeOf(Person))
  If *mem
    InitializeStructure(*mem, Person)
  EndIf
  ProcedureReturn *mem
EndProcedure

Procedure Free(*Struct)
  If *Struct
    ClearStructure(*Struct, Person)
    FreeMemory(*Struct)
  EndIf
EndProcedure

Procedure OutResult(*Struct.Person)
  Debug *Struct\Name$
  Debug *Struct\Age
  
  ForEach *Struct\Friends$()
    Debug *Struct\Friends$()
  Next
EndProcedure

*MyStruct.Person = Create() ; Создали объект.
If *MyStruct
  
  *MyStruct\Name$ = "John"  ; Заполнили поля данными.
  *MyStruct\Age   = 23

  AddElement(*MyStruct\Friends$())
  *MyStruct\Friends$() = "Jim"

  AddElement(*MyStruct\Friends$())
  *MyStruct\Friends$() = "Monica"
  
  OutResult(*MyStruct) ; Отобразили результат.
  
  Free(*MyStruct) ; Уничтожили объект.
  *MyStruct = 0
EndIf

0

3

Пётр написал(а):

*MyStruct.Person = Create() ; Создали объект.

А можно без * и объявления типа?
типа этого

Код:
 
Obj1=MyObj_New()
Obj2=MyObj_New()
if Obj1 and Obj2

  if MyObj_Func1(Obj1,val1,val2)
    .....
  endif

  Name.s=MyObj_Func2(Obj2)

  MyObj_Free(Obj1)
  MyObj_Free(Obj2)
endif

0

4

SadStar написал(а):

А можно без * и объявления типа?

Можно конечно, но первый вариант предпочтительнее.

Код:
Structure Person
  Name$
  Age.l
  List Friends$()
EndStructure

Procedure Create()
  *mem = AllocateMemory(SizeOf(Person))
  If *mem
    InitializeStructure(*mem, Person)
  EndIf
  ProcedureReturn *mem
EndProcedure

Procedure Free(*Struct)
  If *Struct
    ClearStructure(*Struct, Person)
    FreeMemory(*Struct)
  EndIf
EndProcedure

Procedure Func2(*Struct.Person)
  *Struct\Name$ = "John"  ; Заполнили поля данными.
  *Struct\Age   = 23

  AddElement(*Struct\Friends$())
  *Struct\Friends$() = "Jim"

  AddElement(*Struct\Friends$())
  *Struct\Friends$() = "Monica"
EndProcedure

Procedure.s OutResult(*Struct.Person)
  Debug *Struct\Name$
  Debug *Struct\Age
  
  ForEach *Struct\Friends$()
    Debug *Struct\Friends$()
  Next
  
  ProcedureReturn *Struct\Name$
EndProcedure

MyStruct = Create() ; Создали объект.
If MyStruct
  
  Func2(MyStruct)
  
  Name.s=OutResult(MyStruct) ; Отобразили результат.
  Debug Name
  
  Free(MyStruct) ; Уничтожили объект.
  MyStruct = 0
EndIf

0

5

Непонятки по
ClearStructure()
ClearStructure can be used to clear a structured memory area. It's for advanced use only, when pointers are involved.

Чем-то пугают. Не пойму толком - чем.
There is no internal check to ensures than the structure match the memory area. This function is for advanced users only and should be used with care.

Может перед FreeMemory(*Struct)
в явном виде сделать
для строк *Struct\Name$=""
для списка ClearList(*Struct\Friends$() )

P.S.

Допустим есть структура внутри которой другая типа

Код:
Structure ObjHeader
...
EndStructure

Structure ObjField
...
EndStructure

Structure ObjMain
	hFile.l ; хэндл открытого файла
	FullFileName.s
	Header.ObjHeader
	List Fields.ObjField()
	...
EndStructure

Как считать кусок файла в Obj\Header?
ReadData(hFile, *object\Header, 32) не проходит.
ReadData(hFile, @(*object\Header), 32) не проходит.
Прошло ReadData(hFile, *object, 32) когда поставил Header.ObjHeader первым в структуре ObjMain.

Как заполнить элементы списка Fileds() нужными кусками файла?

Отредактировано SadStar (27.10.2011 07:41:48)

0

6

SadStar написал(а):

Чем-то пугают. Не пойму толком - чем.

Может здесь понятнее будет. http://purebasic.ru/manual.php?id=1058&lng=rus

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

Пугают тем, что указатель в первом аргументе, должен соответствовать структуре, указанной во втором аргументе функции ClearStructure(), иначе могут быть ошибки, т. к. очистка выполняется строго в соответствии с типом структуры,  а если тип указан неправильно, то и чистить тоже будет не так, как нужно. Если эти требования выполняются, то все ОК.
Я эту функцию уже не раз использовал, причем на довольно сложных структурах, содержащих много вложенных, списков, массивов, других структур и еще не разу не подводила.

SadStar написал(а):

Как считать кусок файла в Obj\Header?

Смотря что находится в ObjHeader. Если там просто статический массив, то можно поступить так (чтение из файла, для упрощения, заменено на запись в память, это по сути одинаковые операции).

Код:
Structure ObjHeader
  Header.a[32]
EndStructure

Structure ObjField

EndStructure

Structure ObjMain
	hFile.l ; хэндл открытого файла
	FullFileName.s
	Header.ObjHeader
	List Fields.ObjField()
	
EndStructure

object.ObjMain

PokeL(@object\Header, $12345678)

ShowMemoryViewer(@object\Header, SizeOf(object\Header))
SadStar написал(а):

Как заполнить элементы списка Fileds() нужными кусками файла?

С помощью AddElement() добавляешь новый элемент в список. А вот как проще записать туда данные, сильно зависит от содержимого ObjField, хз что там.

0

7

Уточню вопрос.
Есть структура

Код:
Structure ObjHeader
...
EndStructure

Structure ObjField
FieldName.s{11}
FieldType.s{1}
...
EndStructure

Structure ObjMain
	hFile.l ; хэндл открытого файла
	FullFileName.s
	Header.ObjHeader
	List Fields.ObjField()
	...
EndStructure

на её основе создан объект
*object.ObjMain = AllocateMemory(SizeOf(ObjMain))

Как получить адрес начала *object\Header ?
Как получить адрес начала содержимого любого элемента *object\Fields()?

0

8

SadStar написал(а):

Как получить адрес начала *object\Header ?

Код:
*Point = @*object\Header
SadStar написал(а):

Как получить адрес начала содержимого любого элемента *object\Fields()?

Код:
SelectElement(*object\Fields(), НомерЭлемента)
*Point = @*object\Fields()

0


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Как правильно сделать простой конструктор объектов?