Ainda não entendi o que são ponteiros e referências na MQL5 e agora na MQL4. Qual é a diferença entre passar por referência e ponteiro, exceto pelo código extra? Existe uma diferença no C++, mas qual é a diferença aqui? Se não for difícil escrever mais detalhadamente.
A passagem por referência exige que o objeto passado por referência seja inicializado. A passagem por ponteiro não tem essa restrição:
Ao chamar a função TestShapeRef, o código falhará porque a forma não está inicializada. Por outro lado, dentro da função TestShapePointer, são necessárias verificações constantes se o objeto passado está inicializado ou não. Portanto, siga a regra do imprimário:
Se for necessário garantir a existência do objeto no momento em que ele for passado para a função, use uma passagem "&". Se a função exigir um objeto cujo estado seja indefinido, use a passagem pelo ponteiro "*" e, dentro dessa função, verifique a validade do ponteiro passado.
Há mais uma nuance sutil que você deve ter em mente. Considere o exemplo anterior:
Esse programa funcionará corretamente? Não, ele terminará com o erro "acesso a ponteiro inválido" na linha printf(shape.name); //ERROR (!?) , apesar do fato de que parece que temos a garantia de criar um objeto na função TestShapePointer. A questão é que, de fato, uma referência NULL foi passada em vez de shape. Ou seja, a forma dentro da função e a forma passada são objetos diferentes! Assim, depois de sair da função, shape ainda é igual a NULL e o ponteiro de shape dentro da função é perdido (limpo na pilha). Portanto.
É possível criar uma matriz com objetos de tipos diferentes?
Vejamos este exemplo:
//+------------------------------------------------------------------+//|#Teste.mq5//| Copyright 2014, MetaQuotes Software Corp.//|http://www.mql5.com//+------------------------------------------------------------------+#property copyright"Copyright 2014, MetaQuotes Software Corp."#property link"http://www.mql5.com"#property version"1.00"//---#include <ChartObjects\ChartObjectsTxtControls.mqh>
//---
CChartObjectRectLabel rect_label;
CChartObjectButton button;
CChartObjectEdit edit;
//---
CChartObject *objects[];
//+------------------------------------------------------------------+//| Função de início do programa de script|//+------------------------------------------------------------------+voidOnStart()
{
edit.Create(0,"edit_1",0,20,20,100,20);
button.Create(0,"button_1",0,20,40,100,20);
rect_label.Create(0,"rect_label_1",0,20,60,100,20);
//---
AddObjectToArray(edit);
AddObjectToArray(button);
AddObjectToArray(rect_label);
//---//objetos[0]. // Como obter acesso aos métodos da classe CChartObjectEdit?//objetos[1]. // Como obter acesso aos métodos da classe CChartObjectButton?//objetos[2]. // Como obter acesso aos métodos da classe CChartObjectRectLabel?//---while(!IsStopped()) Sleep(1000);
}
//+------------------------------------------------------------------+//| Retorna o número de objetos|//+------------------------------------------------------------------+int ElementsTotal()
{
return(ArraySize(objects));
}
//+------------------------------------------------------------------+//|| Adiciona um objeto à matriz|//+------------------------------------------------------------------+void AddObjectToArray(CChartObject &object)
{
int size=ElementsTotal();
//---ArrayResize(objects,size+1);
objects[size]=GetPointer(object);
//---if(CheckPointer(objects[size])!=POINTER_INVALID)
Print(__FUNCSIG__," >>> array["+IntegerToString(size)+"]: ",objects[size].Name(),
"; object type: ",ObjectTypeToString(objects[size].Type()));
}
//+------------------------------------------------------------------+//| Traduz o tipo de objeto em uma string|//+------------------------------------------------------------------+string ObjectTypeToString(int type)
{
string str="";
//---switch((ENUM_OBJECT)type)
{
caseOBJ_EDIT : return("edit"); break;
caseOBJ_BUTTON : return("button"); break;
caseOBJ_RECTANGLE_LABEL : return("rectangle label"); break;
}
//---return("undefined object type");
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+//||//+------------------------------------------------------------------+class CFoo
{
};
//+------------------------------------------------------------------+//||//+------------------------------------------------------------------+class CBar : public CFoo
{
public:
void func(int x) { Print("Hello from Bar ",x); }
};
//+------------------------------------------------------------------+//||//+------------------------------------------------------------------+void func(CFoo *foo)
{
//--- chamada com conversão diretamente do ponteiro para o tipo de base
((CBar*)foo).func(1);
//--- chamada com conversão para o tipo de destino e salvando uma cópia do ponteiro com o tipo necessário
CBar *b=(CBar *)foo;
b.func(2);
//--- excluir a classe criada dinamicamentedelete foo;
}
//+------------------------------------------------------------------+//||//+------------------------------------------------------------------+voidOnStart()
{
func(new CBar);
}
//+------------------------------------------------------------------+
Ainda não entendi o que são ponteiros e referências na MQL5 e agora na MQL4. Qual é a diferença entre passar por referência e ponteiro, exceto pelo código extra? Existe uma diferença no C++, mas qual é a diferença aqui? Se não for difícil escrever mais detalhadamente.
A passagem por referência exige que o objeto passado por referência seja inicializado. A passagem por ponteiro não tem essa restrição:
Ao chamar a função TestShapeRef, o código falhará porque a forma não está inicializada. Por outro lado, dentro da função TestShapePointer, são necessárias verificações constantes se o objeto passado está inicializado ou não. Portanto, siga a regra do imprimário:
Há mais uma nuance sutil que você deve ter em mente. Considere o exemplo anterior:
Esse programa funcionará corretamente? Não, ele terminará com o erro "acesso a ponteiro inválido" na linha printf(shape.name); //ERROR (!?) , apesar do fato de que parece que temos a garantia de criar um objeto na função TestShapePointer. A questão é que, de fato, uma referência NULL foi passada em vez de shape. Ou seja, a forma dentro da função e a forma passada são objetos diferentes! Assim, depois de sair da função, shape ainda é igual a NULL e o ponteiro de shape dentro da função é perdido (limpo na pilha). Portanto.É possível criar uma matriz com objetos de tipos diferentes?
Vejamos este exemplo:
//---
Como obter acesso a métodos de classes herdadas?
Como acessar métodos de classes herdadas?
Você já tentou lançar um tipo de alvo?
Não. Esta é a primeira vez que ouço falar disso. Onde posso ler sobre isso?
A conversão de tipo usual, aqui está um exemplo:
Você já tentou fazer o casting para o tipo de destino?
Droga, e você está falando sobre segurança de linguagem depois disso?
Não seria melhor usar o polimorfismo?
É mais ou menos assim: