Eclipse(C ++)的未定义引用错误

时间:2018-04-11 14:54:03

标签: c++ eclipse eclipse-cdt header-files undefined-reference

我一直在学习C ++,并且一直在使用一些测试代码来调试更大的项目。我试图使用另一个文件中的对象,但我仍然得到一个未定义的引用错误,尽管包含了相应的头文件。我在Linux上使用Eclipse和C ++ CDT。代码如下所示:

A.cpp

class A {

   private:

      int i;
      int j;

   public:

      A(int i1, int i2) {
         i = i1;
         j = i2;
      }

      int sum() {
         return (i+j);          
      }
};

A.H

#ifndef A_H_
#define A_H_

class A {
   public:
      A(int i1, int i2);
      int sum();
};
#endif

的main.cpp

#include <iostream>
#include "a.h"

int main() {
   A a(1,2); //undefined reference to 'A::A(int,int)'
   std::cout << a.sum(); //undefined reference to 'A::sum(void)'
   return 0;
}

这是我的语法问题,还是我需要在编译器中进行挖掘?

3 个答案:

答案 0 :(得分:0)

问题是main.cpp只看到标题a.h中类的定义,该定义不包含构造函数和成员函数的定义。

A.cpp中定义了这些函数,但默认情况下它们被定义为内联函数。所以main.cpp再次没有看到他们的定义。

考虑到根据C ++标准(3.2一个定义规则)

  

6类类型可以有多个定义(第9条),   枚举类型(7.2),带外部链接的内联函数(7.1.2),   类模板(第14章),非静态函数模板(14.5.6),   类模板的静态数据成员(14.5.1.3),成员函数   一个类模板(14.5.1.1),或模板特化,其中一些   程序中未指定模板参数(14.7,14.5.5)   如果每个定义出现在不同的翻译单元中,   并且提供的定义满足以下要求。特定   这样一个名为D的实体在多个翻译单元中定义,然后

     

(6.1) - D的每个定义应由相同的序列组成   令牌;和

所以在A.cpp中你应该写

#include "a.h"


  A::A(int i1, int i2) {
     i = i1;
     j = i2;
  }

  int A::sum() {
     return (i+j);          
  }

同样,类定义应以分号结束。

答案 1 :(得分:0)

这不是你如何在C ++中拆分类的公共接口和私有实现。

为了使这个代码在main中编译

   A a(1,2);

编译器需要已经知道A的大小 - 这是因为存储是在本地分配的,即使调用初始化它的构造函数是在别处定义的。

你可以通过使用指针(最好是智能指针)或pimpl习语来避免这种耦合,但这是默认的。

这意味着标题中类的定义必须是

class A {
    int i;
    int j;

public:
    A(int i1, int i2);
    int sum();
};

(请注意课程定义末尾的',这很重要 - 您还需要确保使用#endif终止了包含警戒。

实现cpp文件应该看起来像

#include "a.h"

A::A(int i1, int i2) : i(i1), j(i2)
{
}

int A::sum()
{
  return (i+j);          
}

您只允许定义 A一次,因此您不能在标头和实现文件中使用不同的定义。

现在修复了这些问题:如果您的原始错误仍然存​​在,则可能是您的编译/链接设置存在剩余问题。

答案 2 :(得分:0)

每个人都在谈论定义的事情都是正确的。但是还有其他一些问题:

  • 在类定义的右大括号后需要分号;
  • #endif之后需要#ifndef指令(通常位于头文件的最后)
  • 即使使用#include <iostream>cout也不会导出到顶级命名空间。您必须将其称为std::cout

这是一个完整的工作示例。这是一个文件,但如果你想要自己拆分,可以自行拆分:

#ifndef A_H_
#define A_H_

class A {
   private:

      int i;
      int j;

   public:
      A(int i1, int i2);
      int sum();
};
#endif

A::A(int i1, int i2) {
    i = i1;
    j = i2;
}

int A::sum() {
    return (i+j);          
}

#include <iostream>

int main() {
   A a(1,2);
   std::cout << a.sum();
   return 0;
}

Try it out online yourself