【问题标题】:In function undefined reference c++在函数未定义参考 c++
【发布时间】:2018-10-18 11:42:24
【问题描述】:

我总是收到一个奇怪的错误。

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

在函数_start中:>(.text+0x20):未定义对main的引用 /tmp/cc4ZqKzy.o:

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

Building.cpp:(.text+0x3c): 未定义对 Sep::Field::Field() 的引用 收集2:

错误:ld 返回 1 个退出状态

我读了很多关于这个问题的书,但没有一个有相同的。我包括了所有的标题,还添加了 ifndef 保护。

ma​​in.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

#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

#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_;
};

建筑.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

#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(){};

有人知道吗?因为我经常在这个项目中但在其他类中遇到这个错误。 奇怪的是,程序似乎可以正确编译,但在开始时我得到了这个 collect2: error: ld returned 1 exit status。

谢谢

【问题讨论】:

  • Field.cpp 没有实现默认构造函数Field();

标签: c++ class


【解决方案1】:

Field.cpp 需要更改,如果不想使用 Field() 构造函数,只需将 Field() 构造函数的定义置空即可。

例如: 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_;
};

【讨论】:

  • 很好,谢谢,知道为什么我现在收到此错误:'/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux- gnu/crt1.o:在函数_start': (.text+0x20): undefined reference to main''
  • @zwerg4 由于链接器文件/头文件(即 Field.h)无法在任何链接文件中找到 Field() 构造函数的定义,因此给出未定义的引用错误。
【解决方案2】:

当您尝试构造 Building 时,Building::Building(...) 构造函数会隐式调用其基类构造函数 Field::Field()(因为您没有指定您想要的 Field 构造函数)。你在Field.h 中承诺这样的构造函数存在于某个地方(这就是编译器 从不抱怨的原因),但你从未定义它。当 链接器 尝试将您声明的函数与编译器发出的函数链接起来时,它会注意到此构造函数丢失并报错。

这是错误消息试图告诉您的内容:

  • undefined reference to 'Sep::Field::Field()' -> Field::Field() 构造函数未在任何地方定义。

  • In function Sep::Building::Building(...) -> 它正在尝试在显示的Building 构造函数中调用Field 构造函数。

最简单的解决方法是写Field() = default;,这样编译器会自动生成默认构造函数。

编辑:如果你想使用 Field::Field(FieldType) 构造函数,你会这样做:

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

您还可以向 Field 类添加一个构造函数,该类接受您尝试传递的所有这些参数:

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

因此:

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

更好的是,您可以为Building“重用”长 Field 构造函数

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

  // ...
}

【讨论】:

  • 我想在 Building(FieldType 类型, const std::string name, const char 缩写, const bool buildable, const bool destroyable, const unsigned int b_cost, const unsigned int d_cost);构造器将 Fieldtype 作为第一个参数移交,但 Fieldtype 是 Field 的枚举,这就是我使用 Field::Fieldtype::HOME 的原因。那么我怎样才能交出这个枚举呢? Field的构造函数你说的对,我就删了,因为我不需要,
猜你喜欢
  • 2014-07-25
  • 2012-05-22
  • 2012-11-22
  • 2011-09-11
  • 2018-03-02
  • 2021-04-29
  • 2022-01-11
  • 1970-01-01
相关资源
最近更新 更多