es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Llamando a una función en un tercer objeto basado en la combinación de subclases como parámetros.

Estoy planeando representar una lista de nodos.
Mi objeto base Node se puede extender para representar diferentes representaciones y reglas en el futuro.
Por ejemplo, Node1 y Node2 son mis objetos derivados.

class Node {};

<p>class Node1 : public Node {};</p>

<p>class Node2 : public Node {};
<code>
Con fines de personalización, estoy permitiendo que un tercer objeto llamado</code> Rule <code>tenga la función sobrecargada</code> calc <code>para extensiones específicas de</code> Node``` </p>

Así es como imagino que se verá el objeto `Rule`:
<code>
class Rule : public &lt;some not yet defined pure virtual&gt; {
public:
  static void calc(Node n1, Node n2){
    cout &lt;&lt; &quot;Node : Node&quot; &lt;&lt; endl;
  }
  static void calc(Node1 n1, Node n2){
    cout &lt;&lt; &quot;Node1 : Node&quot; &lt;&lt; endl;
  }
  static void calc(Node n1, Node1 n2){
    cout &lt;&lt; &quot;Node : Node1&quot; &lt;&lt; endl;
  }
  static void calc(Node2 n1, Node n2){
    cout &lt;&lt; &quot;Node2 : Node&quot; &lt;&lt; endl;
  }
  static void calc(Node n1, Node2 n2){
    cout &lt;&lt; &quot;Node : Node2&quot; &lt;&lt; endl;
  }
  static void calc(Node1 n1, Node2 n2){
    cout &lt;&lt; &quot;Node1 : Node2&quot; &lt;&lt; endl;
  }
  static void calc(Node2 n1, Node1 n2){
    cout &lt;&lt; &quot;Node2 : Node1&quot; &lt;&lt; endl;
  }
}
</code>
Se pretende que el objeto base de `Rule` pueda ser un objeto virtual puro y deba extenderse o sus extensiones se puedan extender varias veces para incluir sobrecargas de funciones para las extensiones recién definidas de `Node`
<br><br>
<strong>¿Cómo puedo llamar a la función correcta pasando los objetos contenidos en una matriz/vector/lista del objeto base?</strong>

Node n[2];
n[0] = Node2();
n[1] = Node1();

Rule().calc(n[0], n[1]);
“`

Salida deseada: Node2 : Node1

Salida actual: Node : Node
(obviamente, no puedo convertir objetos en ese estado)

Tal vez debería mencionar que, en mi caso particular, es probable que se pase un solo objeto Rule definido entre los objetos Node y termine en llamadas recursivas, ya que estoy intentando algún tipo de propagación.
* ¿Cómo puedo lograr esto?
* ¿Por qué este diseño no funciona o no puede funcionar?
* ¿Se puede solucionar?
* ¿Esto requiere una completa reestructuración del código?
* Si es así, por favor guíame hacia la manera correcta

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para llamar a la función sobrecargada correcta desde el objeto Rule, puedes utilizar enlace dinámico a través de la polimorfia. Puedes declarar una función virtual pura en la clase base Node y sobrescribirla en las clases derivadas Node1 y Node2. Luego, puedes pasar un puntero o una referencia a los objetos Node en lugar de los objetos base Node, lo cual permitirá el enlace dinámico y llamar a la función Rule correcta basada en los objetos derivados actuales pasados.

    Aquí tienes un ejemplo de implementación:

    “`c++
    class Node {
    public:
    virtual ~Node() {} // destructor virtual para liberación segura de memoria
    virtual void calc(Rule& rule, Node& other) = 0; // función virtual pura para enlace dinámico
    };

    class Node1 : public Node {
    public:
    void calc(Rule& rule, Node& other) override {
    rule.calc(*this, other); // llama a la función sobrecargada de Rule basada en los objetos derivados actuales
    }
    };

    class Node2 : public Node {
    public:
    void calc(Rule& rule, Node& other) override {
    rule.calc(*this, other);
    }
    };

    class Rule {
    public:
    // funciones sobrecargadas para extensiones específicas de Node
    static void calc(Node1& n1, Node& n2){
    cout << “Node1 : Node” << endl;
    }
    static void calc(Node& n1, Node1& n2){
    cout << “Node : Node1” << endl;
    }
    static void calc(Node2& n1, Node& n2){
    cout << “Node2 : Node” << endl;
    }
    static void calc(Node& n1, Node2& n2){
    cout << “Node : Node2” << endl;
    }
    static void calc(Node1& n1, Node2& n2){
    cout << “Node1 : Node2” << endl;
    }
    static void calc(Node2& n1, Node1& n2){
    cout << “Node2 : Node1” << endl;
    }
    };

    int main() {
    Node* n[2];
    n[0] = new Node2();
    n[1] = new Node1();

    Rule rule;
    n[0]->calc(rule, *n[1]); // llama a la función de enlace dinámico en punteros Node
    // Salida deseada: Node2 : Node1

    delete n[0]; // libera la memoria
    delete n[1];
    return 0;
    }
    “`

    En esta implementación, la clase base Node declara una función virtual pura calc que toma un objeto Rule y otro objeto Node por referencia. Las clases derivadas Node1 y Node2 sobrescriben esta función y llaman a la función calc adecuada del objeto Rule basada en los objetos derivados actuales pasados.

    En la función main, declaramos un arreglo de punteros de objetos Node y asignamos objetos derivados a él. También creamos un objeto Rule. Luego, llamamos a la función calc en los punteros Node, lo cual permite el enlace dinámico y llama a la función calc sobrecargada correcta basada en los objetos derivados actuales pasados. Finalmente, liberamos la memoria de los objetos Node.

Comments are closed.