Perguntas sobre OOP em MQL5 - página 44

 
Igor Makanu:

Eu discordo:

Por favor, atualize seus conhecimentos sobre o que são "operador de atribuição" e "construtor de cópias", como eles diferem, quando e como são chamados (explícita e implicitamente).
No código você destacou em amarelo o retorno de uma variável local de uma função, o que resulta em chamar o construtor da cópia padrão (não confundir com o operador da atribuição).

O que é um "tipo de dados completo", infelizmente, não é totalmente claro, nem o que você estava tentando provar com seu código...
Vou repetir:"ooperador padrão de atribuição de MQL retorna nulo;"

struct A{
   int x,y;
};

void OnStart(){
   A a, b;
   Print(typename(a = b));   // void
}
 
Koldun Zloy:

Errado.

Basta definir seu operador=, que retorna isso, e ver a diferença.

Você pode ver a diferença quando o resultado da tarefa é atribuído novamente.

Se eu definir operator=, eu perco meu objetivo inicial de chamar o padrão ::=

Parece ser uma questão insolúvel.


Sergey Dzyublik:

O que é "tipo de dados completo", infelizmente, não é muito claro, nem o que você estava tentando provar com seu código...

cheio está cheio - a estrutura de dados será preservada e não há necessidade de controlar a cópia das estruturas se eu acrescentar novos campos

 
Igor Makanu:

Se eu definir operador =, eu fico longe do meu objetivo inicial de chamar o padrão ::=

Você realmente precisa deste tipo de tarefa?

b = c = a;
 
Igor Makanu:

completo está completo - a estrutura de dados será preservada e não há necessidade de controlar a cópia das estruturas se novos campos forem acrescentados

Então, de acordo com sua terminologia, chamar o operador de atribuição padrão poderia dar um "tipo de dados incompletos".
O bug de 2019.05.03 nunca foi corrigido:https://www.mql5.com/ru/forum/1111/page2451#comment_11556395

 
Koldun Zloy:

Você realmente precisa de tal tarefa?

puramente em teoria, eu quero saber se é uma "nova entidade" em vez de um operador =

Não preciso dele para uso prático, não tenho nenhum problema em colocá-lo em 2 operadores


Sergey Dzyublik:

Então, de acordo com sua terminologia, chamar o operador de atribuição padrão pode dar um "tipo de dados incompletos".
O bug de 2019.05.03 nunca foi corrigido:https://www.mql5.com/ru/forum/1111/page2451#comment_11556395

"minha terminologia" é perguntar, sem reclamações,

mas o ponto de usar o operador padrão = é que é conveniente descrever apenas os campos na estrutura, e tudo é copiado, incluindo até as dimensões das matrizes (embora apenas com dimensões crescentes - o princípio do trabalho é o mesmo que no ArrayCopy() )


Bem, se é um bug, deve ser até agora.

 

a questão é puramente teórica:

viram, possivelmente na SB, uma chamada de construtor como esta:

class A{
public:   
   A(){Print(__FUNCTION__);}
};

class B{
public:   
   A a1,a2;
   B():a1(),a2() { Print(__FUNCTION__); }   
};

como este código seria diferente:

class A{
public:   
   A(){Print(__FUNCTION__);}
};

class B{
public:   
   A a1,a2;
   B() { Print(__FUNCTION__); }   
};

Descompactei, não vejo nenhuma diferença, então seja um pouco mais específico - o que ou por que podemos usar uma chamada forçada do construtor para objetos a1 e a2?

qual é a "conveniência" da primeira opção?

 
Igor Makanu:

a questão é puramente teórica:

viram, possivelmente na SB, uma chamada de construtor como esta:

como este código seria diferente:

Descompactei, não vejo nenhuma diferença, então seja um pouco mais específico - qual é o benefício ou por que podemos usar uma chamada forçada do construtor para objetos a1 e a2?

qual é a "conveniência" da primeira opção?

Os construtores podem ter parâmetros e eles têm que ser passados de alguma forma.

Ou seja, até que não haja parâmetros, não há diferença, mas se você usar o construtor A(int arg), é uma história diferente

 
Maxim Kuznetsov:

os construtores têm parâmetros, e eles devem ser passados de alguma forma

Ou seja, até que não haja parâmetros, a diferença é insignificante. Mas se você tem o construtor A(int arg), é uma história diferente

Você provavelmente está certo - depende do propósito

Eu só tive problemas por causa da primeira variante, quando quis usar 2 construtores de classe B e recebi código duplicado em ambos os construtores - eu os removi, e tudo que recebi foi uma parte do código que estava na primeira variante, e a pergunta surgiu onde eu vi e porque eu o escrevi dessa maneira ))))

 
Igor Makanu:

o que dá ou por que os construtores de objetos a1 e a2 podem ser forçados a usar?

O nome correto do processo não é "chamada forçada do construtor a1 e a2", mas inicialização dos campos de classe (não estáticos).
Obrigatório nos casos de:

- Usando campos de classe constante;
- a ausência de um construtor padrão para os campos de classe;
- ausência de qualquer outra forma de inicialização de objetos que não seja através de chamada do construtor (por exemplo, o operador de atribuição é removido);
-...

 

Alguém pode explicar como esta inicialização dos campos é melhor do que isso:

CArray::CArray(void) : m_step_resize(16),
                       m_data_total(0),
                       m_data_max(0),
                       m_sort_mode(-1)
  {
  }

é melhor do que isso:

CArray::CArray(void)
  {
        m_step_resize=16;
        m_data_total=0;
        m_data_max=0;
        m_sort_mode=-1;
  }

E qual é o objetivo, afinal?