Pregunta

Tengo una clase plantada Niño que hereda de una no templada Padre clase. Cuando incluyo NiñoEl encabezado de múltiples archivos .cpp obtengo un error LNK2005. Esto sucede porque Padre se define en múltiples unidades de compilación. Cuando esas unidades se unen, causan el error LNK2005.

En caso de que se lo pregunte, el propósito de Padre es dar Niño una variable estática para todos Niño instancia, no solo uno para cada Niño <'' tipo ''>>.

Mi pregunta es, ¿cómo creo una clase plantada que tiene un único (en todo Niño instancias) variable estática y se puede incluir en múltiples archivos .cpp?

Aquí hay un ejemplo de juguete que causa este error LNK2005:

main.cpp

#include "Apple.h"
#include "Banana.h"

#include <string>

void main() {
    Apple apple;
    Banana banana;
}

Apple.h

#ifndef APPLE_H
#define APPLE_H

struct Apple {
    Apple();
};

#endif // APPLE_H

Apple.cpp

#include "Apple.h"
#include "Child.h"

Apple::Apple() {
    Child<int> child;
    child.foo(5);
}

Plátano.h

#ifndef BANANA_H
#define BANANA_H

struct Banana {
    Banana();
};

#endif // BANANA_H

Banana.cpp

#include "Banana.h"
#include "Child.h"

Banana::Banana() {
    Child<double> child;
    child.foo(3.14);
}

Niño. H

#ifndef CHILD_H
#define CHILD_H

#include <iostream>

using namespace std;

///////////// Parent Class Def ///////////

class Parent {
    protected:
    static int id;
};

int Parent::id = 0;

///////////// Child Class Def ///////////

template <class T>
struct Child : protected Parent {
    Child();
    void foo(T t);
};

template <class T>
Child<T>::Child() {
    id++;
}

template <class T>
void Child<T>::foo(T t) {
    cout << "Child" << id << "'s foo() says: " << t << endl;
}

#endif // CHILD_H

Error LNK2005: "Protegido: static int

¿Fue útil?

Solución

Necesitas definir int Parent::id = 0; Solo una vez en Child.C. Al incluirlo en el encabezado se define una vez por archivo que incluye su encabezado.

Supongo que debo tener en cuenta que entre los males de ponerlo en Parent.C (nombre de clase coincidente) o Child.C Al igualar el nombre del encabezado, elegí la consistencia. Mucho mejor es poner Parent en sus propios archivos para que pueda poner la definición en un apropiado nombrado Parent.C que todavía coincide con el nombre del encabezado correspondiente.

Otros consejos

Jalar

int Parent::id = 0;

hacia Parent.cpp Y estarás bien. Lo que sucede ahora es que la definición se incluye una vez por unidad de traducción que incluye Child.h.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top