OLP. Problemas de aplicación - página 15

 

El constructor por defecto tiene un propósito específico para inicializar una matriz de objetos de su clase. Un constructor con todos sus parámetros establecidos por defecto no es un equipo por defecto. Tut.

He resaltado la errata en rojo.

Por cierto, ¿por qué ese constructor no es un constructor por defecto? ¿Otra muleta?

 
TheXpert:

Un constructor por defectotiene un propósito específico para inicializar un conjunto de objetos de su clase. Un constructor con todos sus parámetros establecidos por defecto no es un equipo por defecto. Aquí

Interesante error tipográfico, gracias. Corregido.
 
Yedelkin:

"Acceso a puntero no válido" =="Intento de acceso a un puntero no válido"?

A menudo es un signo directo de una mala mano o de falta de comprensión de los principios básicos del trabajo con punteros.

Menos a menudo es un signo de uso de la clase mal documentado.

 
TheXpert:

Por cierto, ¿por qué este constructor no es un constructor por defecto? ¿Otra muleta?

Todo lo contrario. La muleta es tener parámetros por defecto, ya que esto es una fuente de errores difíciles de encontrar. Aquí es donde estamos siendo estrictos.

Si escribes un constructor con parámetros, también puedes escribir un constructor sin parámetros. Y si tienes un constructor por defecto, no puedes escribir un constructor paramétrico con todos los parámetros por defecto.

 
stringo:

Es una muleta tener parámetros por defecto, ya que es una fuente de errores difíciles de detectar.

Sí, de alguna manera no se me ocurre ninguna situación de este tipo.

Y si hay un constructor por defecto, no se puede escribir un constructor paramétrico con todos los parámetros por defecto.

Ah, entonces es normal y lógico. Por lo demás, había una especie de ambigüedad incomprensible.
 

He leído sobrela operación de resolución de contexto ( ::: ). Decidí intentar utilizarlo en dos clases no relacionadas:

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class C_B;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class C_A
  {
public:
   C_B              *pointer;

                     C_A(void) {};
                    ~C_A(void) {};
   void funcA(int i) { Print("funcA(",i,")=",i); }
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class C_B
  {
public:
                     C_B(void) {};
                    ~C_B(void) {};
   void funcB(int j)
     {
      Print("funcB(",j,")=",j);
      C_A::funcA(j);
     }
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   C_A object;
   object.pointer=new C_B();
   object.pointer.funcB(5);
   delete object.pointer;
  }

El compilador da un error en la línea C_A::funcA(j). Si lo comento, parece que funciona. ¿Cuál es mi error?

 
Yedelkin:

He leído sobrela operación de resolución de contexto ( ::: ). Decidí intentar utilizarlo en dos clases no relacionadas:

El compilador da un error en la línea C_A::funcA(j). Si lo comento, parece que funciona. ¿Cuál es mi error?

En su caso, el contexto de la clase C_A no está disponible en la clase C_B.

Sólo es correcto si:

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class C_B : public C_A
  {
public:
                     C_B(void) {};
                    ~C_B(void) {};
   void funcB(int j)
     {
      Print("funcB(",j,")=",j);
      C_A::funcA(j);
     }
  };

Pero entonces puede:


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class C_B : public C_A
  {
public:
                     C_B(void) {};
                    ~C_B(void) {};
   void funcB(int j)
     {
      Print("funcB(",j,")=",j);
      funcA(j);
     }
  };


En general, este tipo de llamadas se utilizan para los métodos sobrecargados:


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class C_B;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class C_A
  {
public:
   C_B              *pointer;

                     C_A(void) {};
                    ~C_A(void) {};
   void func(int i) { Print("C_A::func(",i,")=",i); }
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class C_B : public C_A
  {
public:
                     C_B(void) {};
                    ~C_B(void) {};
   void func(int j)
     {
      Print("C_B::func(",j,")=",j);
      C_A::func(j);
     }
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   C_A object;
   object.pointer=new C_B();
   object.pointer.func(5);
   delete object.pointer;
  }

Aproximadamente así.

 
uncleVic:

En su caso, el contexto de la clase C_A no está disponible en la clase C_B.

Gracias. Así que me equivoqué al afirmar que la operación de resolución de contexto puede aplicarse sin herencia.
 

Estoy intentando pasar valores de miembros de una clase a otra "por referencia" y utilizando un descriptor. Ambas opciones parecen funcionar. Este es el esquema más sencillo:

class B
  {
private:
   double            d1;
public:
                     B(double &d) {  d1=d; Print("class B, double d1=",d1);  };
                    ~B(void){};
  };
class A
  {
public:
   double            double_var;
   A                *pointerA;
 

                     A(void) : double_var(1.234567),pointerA(NULL) { SetPointer(); };
                    ~A(void) {if(CheckPointer(pointerA)==POINTER_DYNAMIC) delete pointerA; };
private:
   void SetPointer(void) { pointerA=GetPointer(this); }
  };
class C 
  {
public:
   A                *pointerA_C;
public:
                     C(void) : pointerA_C(NULL) {};
                    ~C(void) {if(CheckPointer(pointerA_C)==POINTER_DYNAMIC) delete pointerA_C;};
   void Printer() {if(CheckPointer(pointerA_C)!=POINTER_INVALID) Print("class C, double =",pointerA_C.double_var); };
  };
void OnStart()
  {
   A objA;
//---передаём значение double-переменной по ссылке
   B objB(objA.double_var);
//---передаём значение double-переменной через описатель
   C objC;
   objC.pointerA_C=objA.pointerA;
   objC.Printer();
  }

¿Cuál de estos dos métodos funciona más rápido? ¿Qué es más preferible?

 
Yedelkin:

Estoy intentando pasar valores de miembros de una clase a otra "por referencia" y utilizando un descriptor. Ambas opciones parecen funcionar. Este es el esquema más sencillo:

¿Cuál de estos dos métodos funciona más rápido? ¿Qué es más preferible?

¿Las preguntas son realmente pesadas/incorrectas?

Durante mucho tiempo utilicé la primera forma ("siguiendo el enlace"), pero me gusta mucho la idea de los descriptores. Sólo que no sé si vale la pena reescribir todas las clases por ello.

Razón de la queja: