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.

¿Cómo devolver derivado de una función como referencia a Base?

Quiero implementar una función que devuelva una referencia a Base que en realidad comprende Derived (los tipos son polimórficos). Algo así como el siguiente código (incorrecto):

struct Base { virtual ~Base() {} };
struct Derived: Base { int x = 5;};

const Base& get() {
    Derived d = {};
    const Base& b = d;
    return b;
}

int main() {
    const Base& b = get();
    const auto* a = dynamic_cast<const a*="">(&b);
}

OBVIAMENTE, este código causa un comportamiento indefinido, ya que b en main es una referencia colgante.

Entonces, supongo que el principal obstáculo es el siguiente:

  • Para ~pasar Derived como Base~, necesitamos crear una referencia. No se puede devolver una referencia a una variable local desde una función, ya que estaría haciendo referencia a una memoria desalocada de la pila.

¿Hay alguna solución para este problema (como usar punteros en lugar de referencias u algo así)?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Sí, hay soluciones alternativas para este problema. Una solución es usar un puntero en lugar de una referencia y asignar el objeto de manera dinámica en el montón para asegurarse de que persista más allá del alcance de la función. Aquí tienes un ejemplo de implementación:

    const Base* get() {
        Derived* d = new Derived();
        const Base* b = d;
        return b;
    }
    
    int main() {
        const Base* b = get();
        const auto* a = dynamic_cast<const derived*="">(b);
        // ahora podemos utilizar 'a' de forma segura
        delete b; // no olvides liberar la memoria asignada
    }
    

    En este ejemplo, la función get crea un nuevo objeto Derived en el montón utilizando new, lo asigna a un puntero Base y devuelve ese puntero. En main, podemos realizar un cast seguro de b a un puntero Derived utilizando dynamic_cast, ya que sabemos que apunta a un objeto Derived. Finalmente, debemos recordar eliminar la memoria asignada utilizando delete.

Comments are closed.