c ++: função de cabeçalho não estar ligado corretamente a partir biblioteca em exe

StackOverflow https://stackoverflow.com/questions/500182

  •  20-08-2019
  •  | 
  •  

Pergunta

Eu tenho um arquivo de cabeçalho em uma biblioteca (alibrary.lib). A biblioteca é uma biblioteca estática (lib) e ele liga corretamente para exe.

Agora, eu tenho uma classe:. Vector3D

class Vector3d 
{
    void amethod()
    {
       blah
    }

};

Vector3d cross(const Vector3d &v0, const Vector3d &v1) 
{
      float x,y,z;

      x = v0.y*v1.z-v0.z*v1.y;
      y = v0.z*v1.x-v0.x*v1.z;
      z = v0.x*v1.y-v0.y*v1.x;

     return Vector3d(x,y,z);

}

Vector3D é declarada e definida em um arquivo de cabeçalho (Vector3D .h). Após a declaração de classe, eu a função de cruz.

A compilação lib é o arquivo, mas quando se liga para o teste de unidade exe eu recebo este erro:

 flywindow.obj :error LNK2005: "class Vector3d __cdecl cross(class Vector3d const &,class Vector3d const &)" (?cross@@YA?AVVector3d@@ABV1@0@Z) already defined in fly.obj

Todas as idéias?

Graças

Foi útil?

Solução

Se você definir um livre (não é um membro de uma classe) função, tem que ser definido em um arquivo .cpp compilados separadamente, ou em um cabeçalho e marcado embutido. Assim, no seu caso, você pode começar afastado tornando-compilar por este:

inline Vector3d cross(const Vector3d &v0, const Vector3d &v1) {
      float x,y,z;

      x = v0.y*v1.z-v0.z*v1.y;
      y = v0.z*v1.x-v0.x*v1.z;
      z = v0.x*v1.y-v0.y*v1.x;

     return Vector3d(x,y,z);

}

O erro é causado porque você tem a definição da função no cabeçalho, mas não marcou-lo em linha. Se você agora incluir esse cabeçalho em dois arquivos que são compilados separadamente, o vinculador, ao tentar vincular os arquivos de objeto compilados, vai jogar fora um erro, porque então vê uma função transversal sendo definido duas vezes.

Ele funciona sem exlicitly colocando em linha para funções de membro de uma classe, porque funções membro que são definidos dentro da definição de classe são implicitamente em linha.

No entanto, é uma boa idéia geral para fazer definições de funções no cabeçalho. Se a sua função vai depender de outros tipos do que apenas o vector (no seu caso É bom IMHO, mas é discutível, claro - algumas pessoas não como ele), então você seria obrigado a incluir os cabeçalhos para esses tipos. Isso vai desnecessariamente inchar o código que está indiretamente incluído por seu cabeçalho. Em vez disso, nos casos em que você apenas colocar apenas uma declaração de sua função dentro do cabeçalho:

Vector3d cross(const Vector3d &v0, const Vector3d &v1);

Mas defini-lo dentro do arquivo .cpp que é compilado separadamente. A linha, é claro, deve então ser descartado.


Deixe-me acrescentar uma pequena lista de definições e declarações, apenas para ajudar a manter as coisas claras sobre o que significa a declaração e definição de funções e classes. Note-se que cada definição é também uma declaração, mas não o contrário:

// class _declaration_ of boo
class boo;

// class _definition_ of foo.
class foo {
    // member function _declaration_ of bar
    void bar();

    // member function _definition_ of baz
    void baz() { }
};

// function _definition_ of fuzz
inline void fuzz() { }

// function _declaration_ of fezz
void fezz();

Outras dicas

A explicação mais provável é que você tem o código (especificamente a definição de cruz) em seu arquivo incluir e seu arquivo de inclusão está sendo incluído por dois arquivos de origem, daí a dupla definição.

Os arquivos de cabeçalho deve ter declarações neles, não definições. Declarações (syaing que algo existe) são coisas como typedef é, declarações de classe, enumeração de e assim por diante.

Definições (dando sentido à thos coisas que existem) são coisas como funções, definições varialble e assim por diante.

A sua função cruz devem ser declarados no arquivo de cabeçalho:

Vector3d cross(const Vector3d &v0, const Vector3d &v1);

mas definido em um arquivo de origem separado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top