IPB
ЛогинПароль:

> 

Наладить общение поможет, если вы подпишитесь по почте на новые темы в этом форуме.

 
 Ответить  Открыть новую тему 
> Fpc, методы класса
сообщение
Сообщение #1


Perl. Just code it!
******

Группа: Пользователи
Сообщений: 4 100
Пол: Мужской
Реальное имя: Андрей

Репутация: -  44  +


Почему я не могу напрямую вызвать метод класса ? ClassName.MethodName ? Просто интересно.

{$N+}
{$mode objfpc}

unit Polinom;

interface

type

  TFloat = Double;

  TCoeff = TFloat;

  TCoeffs = array of TCoeff;

  TPolinom = class

    public

      constructor Create(const n: Word);

      destructor Destroy;

      procedure ReadCoeffs;

      procedure PrintCoeffs(const c: TCoeffs);

      function GetDerivative(const c: TCoeffs): TCoeffs;

      function GetCoeffs: TCoeffs;

      property C: TCoeffs read GetCoeffs;

    private

      coeffs: TCoeffs;

  end;

implementation

constructor TPolinom.Create(const n: Word);
begin
  SetLength(coeffs, n + 1);
end;

destructor TPolinom.Destroy();
begin
  SetLength(coeffs, 0);
end;

function TPolinom.GetCoeffs: TCoeffs;
begin
  result := coeffs;
end;

procedure TPolinom.ReadCoeffs;
var
  i: Integer;
begin
  for i := 0 to Length(coeffs) - 1 do begin
    write('x^', i, ' * ');
    readln(coeffs[i]);
  end;
end;

function TPolinom.GetDerivative(const c: TCoeffs): TCoeffs;
var
  i: Integer;
begin
  SetLength(result, Length(c) - 1);
  for i := Length(c) - 1 downto 1 do
   result [i - 1] := c[i] * i;
end;

procedure TPolinom.PrintCoeffs(const c: TCoeffs);
var
  i: Integer;
begin
  for i := 0 to Length(c) - 1 do
   writeln('c[', i, ']=', c[i]:2:1);
end;

begin
end.


uses Crt, Polinom;

var

  P: TPolinom;

  degree: Integer;

  test: TCoeffs;

begin
  clrscr;


  write('Введите степень полинома : '); readln(degree);

  P := TPolinom.Create(degree);

  P.ReadCoeffs;

  test := P.C;

  TPolinom.PrintCoeffs(test); // <---------------- Вот так нельзя делать ?!

  P.Destroy;

  readln;
end.


--------------------
perl -e 'print for (map{chr(hex)}("4861707079204E6577205965617221"=~/(.{2})/g)), "\n";'
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Гость






А что, собственно, тебя смущает? Ты данные какого экземпляра хочешь напечатать? Из твоей конструкции этого не видно... Вот так - видно:
P.PrintCoeffs(test);
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Perl. Just code it!
******

Группа: Пользователи
Сообщений: 4 100
Пол: Мужской
Реальное имя: Андрей

Репутация: -  44  +


Нет, я хочу вызвать именно метод класса, а не его бъекта, вот как напирмер вызов конструктора
TPlonom.Create(n);


--------------------
perl -e 'print for (map{chr(hex)}("4861707079204E6577205965617221"=~/(.{2})/g)), "\n";'
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Perl. Just code it!
******

Группа: Пользователи
Сообщений: 4 100
Пол: Мужской
Реальное имя: Андрей

Репутация: -  44  +


Вот такое в FPC наверняка ведь можно сделать ?

Код
using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            TMyClass A = new TMyClass();
            TMyClass B = new TMyClass();
            TMyClass C = new TMyClass();

            Console.WriteLine(TMyClass.GetN()); // result == 3
        }
    }

    class TMyClass
    {
        public TMyClass()
        {
            n++;
        }

        public static int GetN()
        {
            return n;
        }

        private static int n;
    }
}


Что-то я запутался. Тут всетаки работа со статическим полем и методом.


--------------------
perl -e 'print for (map{chr(hex)}("4861707079204E6577205965617221"=~/(.{2})/g)), "\n";'
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Гость






Ты про это:
  TPolinom = class
  public
      constructor Create(const n: Word);
      destructor Destroy;

      procedure ReadCoeffs;
      CLASS procedure PrintCoeffs(const c: TCoeffs);

      function GetDerivative(const c: TCoeffs): TCoeffs;
      function GetCoeffs: TCoeffs;
      property C: TCoeffs read GetCoeffs;

    private
      coeffs: TCoeffs;
  end;

...
TPolinom.PrintCoeffs(test);
...

?
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Perl. Just code it!
******

Группа: Пользователи
Сообщений: 4 100
Пол: Мужской
Реальное имя: Андрей

Репутация: -  44  +


Ага yes2.gif а что это значит ?)))


--------------------
perl -e 'print for (map{chr(hex)}("4861707079204E6577205965617221"=~/(.{2})/g)), "\n";'
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Гость






Цитата(ref.pdf)
6.3.3 Class methods
Class methods are methods that do not have an instance, but which follow the scoping and inheritance rules of a class. They can be called from inside a regular method, but can also be called using a class identifier:
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Perl. Just code it!
******

Группа: Пользователи
Сообщений: 4 100
Пол: Мужской
Реальное имя: Андрей

Репутация: -  44  +


Все время забываю про этот мануал smile.gif

Класс smile.gif

Спасибо !


--------------------
perl -e 'print for (map{chr(hex)}("4861707079204E6577205965617221"=~/(.{2})/g)), "\n";'
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Ищущий истину
******

Группа: Пользователи
Сообщений: 4 825
Пол: Мужской
Реальное имя: Олег

Репутация: -  45  +


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


--------------------
Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


Perl. Just code it!
******

Группа: Пользователи
Сообщений: 4 100
Пол: Мужской
Реальное имя: Андрей

Репутация: -  44  +


Вот ты не прав. Зачем - то же умные люди дали нам возможность так писать программы ... Да и примеров таких методов не мало. Сущность без индивидуальности... это ты куда-то не туда копать начал, мне кажется smile.gif


--------------------
perl -e 'print for (map{chr(hex)}("4861707079204E6577205965617221"=~/(.{2})/g)), "\n";'
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


Гость






Олег, тривиальная задача: посчитать, сколько экземпляров моего класса создано в программе...
Твое решение без Class Methods ?
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12


Ищущий истину
******

Группа: Пользователи
Сообщений: 4 825
Пол: Мужской
Реальное имя: Олег

Репутация: -  45  +


Цитата
это ты куда-то не туда копать начал, мне кажется

Вообще-то индивидульность объекта - одно из фундаментальных принципов ООП....

Цитата
Олег, тривиальная задача: посчитать, сколько экземпляров моего класса создано в программе...
Твое решение без Class Methods ?

Спасибо! Идея ясна...
т.е. если я верно понял, таким-же образом, например, можно проверить, что создаваемый объект будет с уникальными свойствами, да ?

Иллюстрация:
Есть класс ТочкаНаПлоскости.
И допустим конструктор при инициализации объекта - экземпляра класса ТочкаНаПлоскости, задает координаты точки случайно...
Тогда, что бы например, при инициализации проверить что точка не совпадет ни с какой другой можно использовать метод класса, который проверит есть ли экземпляры с такими свойствами...

Иллюстрация верна ?


--------------------
Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #13


Гость






Цитата
можно использовать метод класса, который проверит есть ли экземпляры с такими свойствами...
То, что выделено красным - несовместимо...

Понимаешь, в чем дело... В Class Method-е ты не можешь обращаться к данным класса/НЕ-классовым методам/свойствам... По одной простой причине: в момент, когда ты вызываешь Class Method у тебя может не быть ни одного экземпляра класса. То есть, проверить что-либо, касаемое экземпляров именно этого класса у тебя не выйдет.

Вот еще один классический пример использования:
НДС (ну, или любой другой налог), взимаемый за, скажем, услугу, описываемую типом T, изначально равен 17%... В какой-то момент этот налог увеличивается. При инициализации нового экземпляра класса мы должны увидеть новое значение налога, и при обработке информации, связанной с T (!!!), тоже будет рассматриваться новое значение. Что делаем?
{$mode ObjFPC}
unit unit_1;

interface

type
  T = class
    constructor init();

    class procedure set_VAT(vat_value: double);
  end;

implementation

var
  VAT: double = 0.17;

constructor T.init();
begin
  writeln('VAT = ', VAT:10:5);
end;

class procedure T.set_VAT(vat_value: double);
begin
  VAT := vat_value;
end;

end.

Используем так:
uses unit_1;

var
  obj_1, obj_2: T;

begin
  obj_1 := T.init();
  T.set_VAT(0.19);
  obj_2 := T.init();
  ...
end.


Я знаю, что ты скажешь: "А почему бы не просто функция (вообще вне класса), которая будет изменять переменную? Или вообще напрямую изменять переменную, безо всяких функций... Зачем навороты?" Так?

Не так...
То, что напрямую - это нарушается принцип упрятывания информации, значит придется работать-таки через какой-то интерфейс. Простая функция? Да ни в коем случае... Я же сказал, что VAT - это налог за услугу T, а если будет 2 услуги? T и R, например? Налог на T один, на R - другой... Почему не просто метод в классе T? Потому, что у меня может не быть ни одного экземпляра инициализировано, а придется менять VAT. Создавать временный экземпляр, а потом удалять его - глупо.

Поэтому делаем Class Procedure, и программа становится прозрачной... Даже если у меня уже и есть инициализированные экземпляры класса T, я предпочту сделать НЕ так:
obj_1.set_VAT(0.19);
, а вот так:
T.set_VAT(0.19);
, потому, что налог распространяется НЕ на один какой-то экземпляр услуги, а на весь ее тип !!!

Понимаешь, в чем вся идея? Ты пользуешься Class Method-ами тогда, когда тебе нужно сделать что-то, что характерно НЕ для экземпляра, а в целом для класса...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #14


Perl. Just code it!
******

Группа: Пользователи
Сообщений: 4 100
Пол: Мужской
Реальное имя: Андрей

Репутация: -  44  +


А можно на fpc написать именно аналог кода приведенного мною на шарпе ? Чтобы для всех экземпляров существовала единая статическая переменная - счетчик, которая находилась бы внутнри описания класса ?

Или на обжэкт паскале такое нельзя замутить ?

Добавлено через 5 мин. 42 сек.
В сети пока везде нахожу только один и тотже пример на подобии приведенного volvo (размещать счетчик ну или просто какую-то общую переменную в имплементейшн разделе модуля)


вот он например

http://www.cracklab.ru/pro/faq.php?pg=3586


--------------------
perl -e 'print for (map{chr(hex)}("4861707079204E6577205965617221"=~/(.{2})/g)), "\n";'
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #15


Гость






Цитата(ref.pdf)
Inside a class method, the self identifier points to the VMT table of the class. No fields, properties or regular methods are available inside a class method. Accessing a regular property or method will result in a compiler error. The reverse is possible: a class method can be called from a regular method.
...
Class methods cannot be used as read or write specifiers for a property.
Именно поэтому приходится работать не с полями класса, а с внешней (по отношению к классу) переменной...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #16


Гость






Хотя, естественно, обмануть компилятор можно:
{$mode ObjFPC}
type
  T = class

    constructor init();

    class function count(access: boolean): integer;
    class function get_count(): integer;

  end;

constructor T.init();
begin
  count(true);
end;

class function T.count(access: boolean): integer;
const
  counter: integer = 0;
begin
  if access then inc(counter);
  count := counter;
end;

class function T.get_count(): integer;
begin
  get_count := count(false);
end;


{ main }
const
  n = 10;
var
  arr: array[1 .. n] of T;
  i: integer;

begin
  for i := 1 to 7 do arr[i] := T.init();

  writeln(T.get_count(), ' init calls ...');
end.

 К началу страницы 
+ Ответить 
сообщение
Сообщение #17


Perl. Just code it!
******

Группа: Пользователи
Сообщений: 4 100
Пол: Мужской
Реальное имя: Андрей

Репутация: -  44  +


Здорово smile.gif good.gif


--------------------
perl -e 'print for (map{chr(hex)}("4861707079204E6577205965617221"=~/(.{2})/g)), "\n";'
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



- Текстовая версия 22.04.2025 2:06
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name