简体   繁体   English

在函数中未定义的参考C ++

[英]In function undefined reference c++

I get a strange error all the time. 我总是遇到一个奇怪的错误。

/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o:

In function _start: >(.text+0x20): undefined reference to main /tmp/cc4ZqKzy.o: 在函数_start中:>(。text + 0x20):对主/tmp/cc4ZqKzy.o的未定义引用:

In function `Sep::Building::Building(Sep::Field::FieldType, >std::__cxx11::basic_string, >std::allocator >, char, bool, bool, unsigned int, unsigned int): 在函数`Sep :: Building :: Building(Sep :: Field :: FieldType,> std :: __ cxx11 :: basic_string,> std :: allocator>,char,bool,bool,unsigned int,unsigned int)中:

Building.cpp:(.text+0x3c): undefined reference to Sep::Field::Field() collect2: Building.cpp :(。text + 0x3c):对Sep :: Field :: Field()的未定义引用collect2:

error: ld returned 1 exit status 错误:ld返回1退出状态

I read a lot with this problem but none had the same. 对于这个问题,我读了很多,但没有一个有相同的。 I included all the headers and also added ifndef guards. 我包括了所有标题,还添加了ifndef防护。

main.cpp: main.cpp中:

#include "Field.h"
#include "Building.h"

namespace Sep
{
  just some returns...
}

int main(int argc, char *argv[])
{
  Sep::Building Haus(Sep::Field::FieldType::HOME,"HOME", 'H', true, true, 100, 100);
  std::cout << "HAUS ABREV:" << Haus.getAbbrevationOnField() << '\n';
}

Field.h Field.h

#include <cstring>
#include <string>
#include <iostream>
#include <memory>


#ifndef FIELD_H
#define FIELD_H

namespace Sep
{

  //----------------------------------------------------------------------------
  // Field class, containing all needed information to create a Field object
  //
  class Field
  {
    public :
      enum FieldType \
      {GRASS, WATER, OBSTACLE, STREET, HOME, MARKET, CLINIC, TOWNHALL};

    private:
      FieldType type_;
      std::string name_;
      char abbrevation_;
      bool buildable_;
      bool destroyable_;
      unsigned int build_cost_;
      unsigned int destroy_cost_;

    public:
      //------------------------------------------------------------------------
      // Field constructors & destructor
      //
      Field();
      Field(FieldType type);
      ~Field() noexcept;
      //------------------------------------------------------------------------
      //getters
      //
      Field::FieldType getFieldType() const { return type_; };
      const char getAbbrevationOnField() const { return abbrevation_; };

  //------------------------------------------------------------------------
  //setters
  //
      static std::string getName(FieldType type);
      FieldType getType() const;//steht oben in getFiel3dType Z55

      void setType(FieldType type){type_ = type;};
      void setName(std::string name){name_ = name;};
      void setAbbrevation(char abbrev){abbrevation_ = abbrev;};
      void setBuildable(bool buildable){buildable_ = buildable;};
      void setDestroyable(bool destroyable){destroyable_ = destroyable;};
      void setBuildCost(int b_cost){build_cost_ = b_cost;};
      void setDestroyCost(int d_cost){destroy_cost_ = d_cost;};
  };
}

#endif //FIELD.H

Field.cpp Field.cpp

#include "Field.h"
#include <cstring>
#include <string>
#include <iostream>
#include <memory>

using Sep::Field;


//------------------------------------------------------------------------------
// Setter of the private FieldType type_ to the given param
//
// @param the type of field to get set
//
Field::Field(FieldType type)
{
  type_ = type;
};

Field::~Field(){};

//------------------------------------------------------------------------------
// Checks the type of a given field, returns the name of type as string
//
// @param type, the type of the field to check
//
// @return string the name of the type of the checked field
//
std::string Field::getName(FieldType type)
{
  switch (type)
  {
    case GRASS:
      return std::string("Grass");
    case WATER:
      return std::string("Water");
    case OBSTACLE:
      return std::string("Obstacle");
    case STREET:
      return std::string("Street");
    case HOME:
      return std::string("Home");
    case MARKET:
      return std::string("Market");
    case CLINIC:
      return std::string("Clinic");
    case TOWNHALL:
      return std::string("Town Hall");
    default:
      return std::string("Unknown Field");
  }
};

//------------------------------------------------------------------------------
// getters
//
// Getter from the private FieldType type_
//
// @param none
//
// @return the type of type_ as FieldType
//
Field::FieldType Field::getType() const
{
  return type_;
};

Building.h Building.h

#ifndef BUILDING_H
#define BUILDING_H

#include "Field.h"

namespace Sep
{
  class Building : public Field
  {
    private:

    public:
    Building(FieldType type, const std::string name, const char abbrevation, \
           const bool buildable, const bool destroyable,\
           const unsigned int b_cost, const unsigned int d_cost);
    ~Building();
  };
}

#endif //BUILDING_H

Building.cpp Building.cpp

#include "Building.h"
#include "Field.h"

Sep::Building::Building(FieldType type, const std::string name, \
         const char abbrevation, \
         const bool buildable, const bool destroyable,\
         const unsigned int b_cost, const unsigned int d_cost)
{
  Sep::Field::setType(type);
  Sep::Field::setName(name);
  Sep::Field::setAbbrevation(abbrevation);
  Sep::Field::setBuildable(buildable);
  Sep::Field::setDestroyable(destroyable);
  Sep::Field::setBuildCost(b_cost);
  Sep::Field::setDestroyCost(d_cost);
};

Sep::Building::~Building(){};

Has anyone a idea? 有人知道吗? Cause I get this error often in this project but in other classes. 原因我经常在该项目中但在其他类中遇到此错误。 The strange thing is that it seems like, that the program compiles correctly but on the start I get this collect2: error: ld returned 1 exit status. 奇怪的是,程序似乎可以正确编译,但是一开始我得到的是collect2:错误:ld返回了1退出状态。

Thx 谢谢

When you are trying to construct a Building , the Building::Building(...) constructor implicitly calls its base class constructor Field::Field() (since you did not specify which Field constructor you want). 当您尝试构造BuildingBuilding::Building(...)构造函数隐式调用其基类构造函数Field::Field() (因为未指定所需的Field构造函数)。 You promised in Field.h that such a constructor exists somewhere (which is why the compiler never complains), but you never define it. 您在Field.h中承诺了这样的构造函数存在于某个地方(这就是为什么编译器从不抱怨的原因),但是您从未定义它。 When the linker then tries to link the functions you declared with the functions that the compiler emitted, it notices that this constructor is missing and complains. 然后,当链接器尝试将您声明的函数与编译器发出的函数链接时,它会注意到此构造函数丢失并抱怨。

This is what the error messages are trying to tell you: 这是错误消息试图告诉您的内容:

  • undefined reference to 'Sep::Field::Field()' -> The Field::Field() constructor is not defined anywhere. undefined reference to 'Sep::Field::Field()' -> Field::Field()构造函数未在任何地方定义。

  • In function Sep::Building::Building(...) -> It is trying to call the Field constructor in the shown Building constructor. In function Sep::Building::Building(...) ->中,它试图在所示的Building构造函数中调用Field构造函数。

The simplest fix is to write Field() = default; 最简单的解决方法是编写Field() = default; so the compiler automatically generates the default constructor. 因此,编译器会自动生成默认构造函数。

Edit: If you want to use the Field::Field(FieldType) constructor, this is how you would do that: 编辑:如果您想使用Field::Field(FieldType)构造函数,这是您要这样做的方式:

Building::Building(FieldType fieldType, /* etc */)
  : Field(fieldType)
{
  // etc.
}

You could also add a constructor to the Field class that takes all these arguments that you are trying to pass: 您还可以向Field类添加一个构造函数,该构造函数接受您尝试传递的所有这些参数:

Field::Field(FieldType fieldType, std::string name, char abbrevation, /* etc. */)
  : type_(fieldType), name_(name), abbrevation_(abbreviation), /* etc. */
{
}

And thus: 因此:

Building::Building(FieldType type, const std::string name, const char abbrevation, /* etc. */)
  : Field(type, name, abbreviation, /* etc. */)
{
}

Even better, you can just "reuse" the long Field constructor for Building 更好的是,您可以仅“重用”冗长的Field构造函数以进行Building

class Building : public Field
{
public:
  using Field::Field;

  // ...
}

Field.cpp need to be changed, if don't want to used Field() constructor just put the definition of Field() constructor empty. 如果不想使用Field()构造函数,只需将Field()构造函数的定义为空,就可以更改Field.cpp。

For examples: Field.cpp 例如: Field.cpp

#include "Field.h"
#include <cstring>
#include <string>
#include <iostream>
#include <memory>

using Sep::Field;


//------------------------------------------------------------------------------
// Setter of the private FieldType type_ to the given param
//
// @param the type of field to get set
//
Field::Field(){ 

       //empty constructor or can initialize type_ to default value.
   }


Field::Field(FieldType type)
{
  type_ = type;
};

Field::~Field(){};

//------------------------------------------------------------------------------
// Checks the type of a given field, returns the name of type as string
//
// @param type, the type of the field to check
//
// @return string the name of the type of the checked field
//
std::string Field::getName(FieldType type)
{
  switch (type)
  {
    case GRASS:
      return std::string("Grass");
    case WATER:
      return std::string("Water");
    case OBSTACLE:
      return std::string("Obstacle");
    case STREET:
      return std::string("Street");
    case HOME:
      return std::string("Home");
    case MARKET:
      return std::string("Market");
    case CLINIC:
      return std::string("Clinic");
    case TOWNHALL:
      return std::string("Town Hall");
    default:
      return std::string("Unknown Field");
  }
};

//------------------------------------------------------------------------------
// getters
//
// Getter from the private FieldType type_
//
// @param none
//
// @return the type of type_ as FieldType
//
Field::FieldType Field::getType() const
{
  return type_;
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM