2

Tengo un error y no se como resolverlo, informcion extra es: Visual studio 2017, en un empty project.

LNK2019 unresolved external symbol "public: static void __cdecl Biseccion::inicio(void)" (?inicio@Biseccion@@SAXXZ) referenced in function _main

Source.cpp:

#include "Biseccion.h"
using namespace std;
int main() {
    //Biseccion * bi = new Biseccion();
    Biseccion bi;
    bi.inicio();
    system("PAUSE");
    return 0;
}

Biseccion.h:

#pragma once
#include <stdlib.h>
#include <iostream>
#include <stdio.h>
#include <string>
#include "Ecuacion.h"

using namespace std;
class Biseccion {
public:
    static void inicio(void);
    Biseccion(void);
};

Biseccion.cpp:

#include <stdlib.h>
#include <iostream>
#include <stdio.h>
#include <string>
#include "Ecuacion.h"

using namespace std;
class Biseccion {
private:
    int longitudEcua = 0;
    Ecuacion * ecuat;
    vector<double> * preguntarArray() {
//codigo del metodo
        return &ecu;
    }

public:
    void inicio(void) {
//Codigo del metodo
    }
    Biseccion();
};

Biseccion::Biseccion() { ; }

Ecuacion.h:

#pragma once
#include <vector>
#include <math.h>

using namespace std;
class Ecuacion {
public:
    void setEcua(vector<double> * s);
    vector<double>* getEcua(void);
    Ecuacion(int);
    double getPosicion(int x);
    void setPosicion(int x, double val);
    double calculaEcua(double x);
};

Ecuacion.cpp:

#include <vector>
#include <math.h>

using namespace std;
class Ecuacion {
private:
    int siseX;
    vector<double>  ecua;
public:

    void setEcua(vector<double> * s) { ecua = *s; };
    vector<double>* getEcua() { return &ecua; }
    Ecuacion(int);

    double getPosicion(int x) {
        return ecua.at(x);
    };
    void setPosicion(int x, double val) {
        ecua.insert(ecua.begin() + x, val);
    }
    double calculaEcua(double x) {
//codigo del metodo
};

Ecuacion::Ecuacion(int x) {
//constructor
}

2 Answers2

3

En C++ no es necesario usar void como parámetro

En C, si no le ponemos void a una función que no recibe parámetros la misma podrá recibir un número indeterminado de ellos:

void func1();     // func admite parametros: func1(1,2,3,4,5);
void func2(void); // func2 NO admite parametros. solo func2() es llamada valida

Sin embargo en C++ no es así. Si una función no tiene parámetros, no admitirá parámetros. Así que dado que void sobra, no lo uses. Dejarás el código más limpio.

// Evitar esto
class Biseccion {
public:
    static void inicio(void);
    Biseccion(void);
};

// Mejor asi
class Biseccion {
public:
    static void inicio();
    Biseccion();
};

No uses using namespace en los archivos de cabecera

Más información aquí: ¿Por qué el usar "using namespace std;" se considera mala práctica?

La declaración de cada clase debe ser única

El código que muestras actualmente tiene dos declaraciones de cada clase:

Biseccion.h:

using namespace std;
class Biseccion { // <<--- DECLARACION
public:
    static void inicio(void);
    Biseccion(void);
};

Biseccion.cpp:

class Biseccion { // <<--- DECLARACION
private:
    int longitudEcua = 0;
    Ecuacion * ecuat;
    vector<double> * preguntarArray() {
//codigo del metodo
        return &ecu;
    }

Y lamento informarte de que eso no va a funcionar en la vida. La declaración de una clase debe ser única, es decir, solo puedes tener una en todo el programa. Además, esa declaración debe ser completa, es decir, debe incluir todas las variables y funciones de la clase.

El motivo es bien simple: El compilador necesita conocer, desde el principio, los requisitos de una clase (tamaño en memoria, ubicación de cada variable, funciones que sean estáticas, constructores disponibles, ...).

Usando como muestra la clase Biseccion, su disposición podría ser la siguiente:

Biseccion.h

class Biseccion {
private:
    int longitudEcua = 0;
    Ecuacion * ecuat;

    vector<double> * preguntarArray();

public:
    void inicio();
    Biseccion();
};

Biseccion.cpp

#include "Biseccion.h"

Biseccion::Biseccion()
{ /* ... */ }

void Biseccion::inicio()
{ /* ... */ }

vector<double>* preguntarArray()
{ /* ... */ } // <<--- ecu no existe
eferion
  • 49,291
  • 5
  • 30
  • 72
1

El enlazador te está diciendo que has declarado la función static void Biseccion::inicio(void), pero no la has definido, puedes ver más detalles en este hilo.


En tu cabecera (.h) declaras la función como estática:

class Biseccion {
public:
    static void inicio(void); // Estática
    Biseccion(void);
};

En tu archivo de código (.cpp) defines la función como miembro:

class Biseccion {
private:
    int longitudEcua = 0;
    Ecuacion * ecuat;
    vector<double> * preguntarArray() {
//codigo del metodo
        return &ecu;
    }

public:
    void inicio(void) { // Función miembro, ¡no función estática!
//Codigo del metodo
    }
    Biseccion();
};

Para el compilador la versión estática y la versión miembro son funciones diferentes, así que tienes una función static void Biseccion::inicio(void) declarada pero no existe la parte definida.

Para solucionarlo, sigue los excelentes consejos de eferion y marca la definición también como estática.

PaperBirdMaster
  • 44,474
  • 6
  • 44
  • 82