Получить адрес перегруженного конструктора классов в Delphi [duplicate]

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

  1. Доступность (область действия) функции

Выполняется следующее, поскольку function add() имеет область действия до ближайшего блока:

try {
  console.log("Success: ", add(1, 1));
} catch(e) {
  console.log("ERROR: " + e);
}

function add(a, b){
  return a + b;
}

Следующее не работает (потому что var add= superseeds function add()).

try {
  console.log("Success: ", add(1, 1));
} catch(e) {
  console.log("ERROR: " + e);
}

var add=function add(a, b){
  return a + b;
}

Не работает, поскольку add объявлен после использования.

try {
  console.log("Success: ", add(1, 1));
} catch(e) {
  console.log("ERROR: " + e);
}

var add=function(a, b){
  return a + b;
}
  1. (function) .name

Имя функции function thefuncname(){} является thefuncname , когда оно объявлено таким образом.

function foobar(a, b){}

console.log(foobar.name);

var a = function foobar(){};

console.log(a.name);

В противном случае, если функция объявлена ​​как function(){} , функция .name является первой переменной, используемой для хранения функции.

var a = function(){};
var b = (function(){ return function(){} });

console.log(a.name);
console.log(b.name);

Если нет переменные, установленные для функции, то имя функции - это пустая строка ("").

console.log((function(){}).name === "");

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

var a = function(){};
var b = a;
var c = b;

console.log(a.name);
console.log(b.name);
console.log(c.name);
  1. Производительность

В Google V8 и Firefox Spidermonkey может быть несколько разметок компиляции Microsecond JIST, но в итоге результат будет таким же. Чтобы убедиться в этом, давайте рассмотрим эффективность JSPerf в microbenchmarks, сравнив скорость двух фрагментов кода. Тесты JSPerf найдены здесь . И jsben.ch тесты найдены здесь . Как вы можете видеть, есть заметная разница, когда их не должно быть. Если вы действительно такой урод, как я, то это может быть более полезно, если вы попытаетесь уменьшить количество переменных и функций в области действия и, в частности, устранить полиморфизм (например, использовать одну и ту же переменную для хранения двух разных типов).

Что такое «ближайший блок»

«Ближайший блок» - ближайшая «функция» (включая асинхронные функции, функции генератора и функции асинхронного генератора). Однако интересно, что function functionName() {} ведет себя как var functionName = function() {}, когда в блоке не замыкания элементы вне указанного закрытия.

  • Обычный var add=function(){}

try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}');
  }
} catch(e) {
  console.log("Is a block");
}
var add=function(a, b){return a + b}
  • Обычный function add(){}

try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}')
  }
} catch(e) {
  console.log("Is a block");
}
function add(a, b){
  return a + b;
}
  • Функция

try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}')
  }
} catch(e) {
  console.log("Is a block");
}
(function () {
    function add(a, b){
      return a + b;
    }
})();
  • Заявление (например, if, else, for, while, try / catch / finally, switch, do / while, with)

try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}')
  }
} catch(e) {
  console.log("Is a block");
}
{
    function add(a, b){
      return a + b;
    }
}
  • Функция стрелки с var add=function()

try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}')
  }
} catch(e) {
  console.log("Is a block");
}
(() => {
    var add=function(a, b){
      return a + b;
    }
})();
  • Функция стрелки С помощью function add()

try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}')
  }
} catch(e) {
  console.log("Is a block");
}
(() => {
    function add(a, b){
      return a + b;
    }
})();

8
задан Matt 12 June 2013 в 20:04
поделиться

2 ответа

На основании this thread и того, что там указано Томаса Мюллера , вы можете определить типы с теми же сигнатурами, что и методы, адреса которых вы хотите получить (для каждой перегрузки) , Если вы затем объявите переменные этих типов и назначите им указатели на объекты, вы убедитесь, что компилятор выбирает правильную перегрузку для вашего известного типа переменной и, кроме того, что она не будет игнорировать их, если они не будут использоваться нигде в коде (некоторые перегрузки не могут быть связаны в вашем двоичном коде).

Поэтому, основываясь на его идее, он может искать перегрузку функции MessageDlgPosHelp следующим образом:

type
  TMessageDlgPosHelp1 = function(const Msg: string; DlgType: TMsgDlgType;
    Buttons: TMsgDlgButtons; HelpCtx: Longint; X, Y: Integer;
    const HelpFileName: string): Integer;
  TMessageDlgPosHelp2 = function(const Msg: string; DlgType: TMsgDlgType;
    Buttons: TMsgDlgButtons; HelpCtx: Longint; X, Y: Integer;
    const HelpFileName: string; DefaultButton: TMsgDlgBtn): Integer;

procedure TForm1.Button1Click(Sender: TObject);
var
  MessageDlgPosHelp1: TMessageDlgPosHelp1;
  MessageDlgPosHelp2: TMessageDlgPosHelp2;
begin
  MessageDlgPosHelp1 := MessageDlgPosHelp;
  MessageDlgPosHelp2 := MessageDlgPosHelp;
  ShowMessage(Format('%p; %p', [@MessageDlgPosHelp1, @MessageDlgPosHelp2]));
end;
15
ответ дан Jeroen Wiert Pluimers 22 August 2018 в 00:16
поделиться

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

0
ответ дан Nashev 22 August 2018 в 00:16
поделиться
  • 1
    В этом случае перегруженные методы являются «глобальными» методами – Nicholas Ring 17 March 2017 в 07:55
  • 2
    Когда вы говорите «глобальный метод», Вы имели в виду процедуру или функцию единицы, а не метод какого-либо класса или записи? В этом случае вы можете просто добавить собственную процедуру или функцию обертки с собственным именем и просто вызвать этот «глобальный метод». внутри них. Без всяких кастинговых трюков. – Nashev 22 March 2017 в 09:36
  • 3
    Да - «глобальный метод» является функцией / процедурой единицы, а не классом / записью. Поскольку этот элемент близок к полувеку назад, я думаю, что после решения, которое перенаправило бы все (в данном случае) методы MessageDlg на собственный метод, без необходимости касаться большого количества файлов в базе кода. В конце концов, мы пошли так, меняя вызовы, когда мы их находим. – Nicholas Ring 23 March 2017 в 21:09
Другие вопросы по тегам:

Похожие вопросы: