“对‘A::A(int,int)’的未定义引用:从包含的标头创建类的对象时

问题描述 投票:0回答:3

我正在尝试使用另一个文件中的对象,但尽管包含了适当的头文件,但我仍然收到未定义的引用错误。我在 Linux 上使用带有 C++ CDT 插件的 Eclipse。

代码如下所示:

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

这是我的语法问题吗,还是我需要在编译器中深入研究?

c++ header-files undefined-reference
3个回答
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);          
  }

类定义也应以分号结束。


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);          
}

您只能 define

A
一次,因此您不能在标头和实现文件中有不同的定义。

现在这些问题已得到解决:如果原来的错误仍然存在,则残留问题可能与您的编译/链接设置有关。


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

自己上网尝试一下

© www.soinside.com 2019 - 2024. All rights reserved.