【问题标题】:Am I creating an object correctly in the header file?我是否在头文件中正确创建了一个对象?
【发布时间】:2020-03-15 00:50:39
【问题描述】:

所以我正在尝试使用类来做一个链表。我从未在 C++ 上使用过类。我想要做的只是在头文件上创建一个类 palabra 的对象。

我想访问 .cpp 文件中的 primeaPalabra 以获取以后的方法。我无法创建对象。

我得到的错误是:“primeraPalabra”的多个定义。

我对头文件和 cpp 文件的使用也很陌生。任何提示表示赞赏。

palabra.h 文件

#ifndef PALABRA_H_INCLUDED
#define PALABRA_H_INCLUDED

#include <iostream>
using namespace std;


class Palabra{
    private:
    int p_id;
    string p_nombre;
    int p_valor;

    Palabra *next;
    Palabra *prev;


public:
    Palabra(int id, string nombre);
    void printNombre();
    int calcularValorPalabra();

    void agregarSiguiente(Palabra *);
    void eliminar();
    void buscar();
};

Palabra primeraPalabra(0,"");
Palabra ultimaPalabra(0, "");
Palabra palabraTemp(0, "");


#endif // PALABRA_H_INCLUDED

palabra.cpp 文件

Palabra::Palabra(int id, string nombre)
    {
    p_id = id;
    p_nombre = nombre;
    p_valor = calcularValorPalabra();

    next = NULL;
    prev = NULL;
}

【问题讨论】:

  • 您不会在标题中创建对象。应该在需要的地方创建它们,例如 main()?
  • 好的,所以我有一个 main()。问题是在我的 .cpp 文件中,我在一个方法中引用了primeraPalabra。我想要的是访问 .cpp 文件上的对象“primeraPalabra”。说,有点像全局变量?有没有更好的方法来做到这一点?
  • 最好不要使用全局变量。

标签: c++ class object header-files


【解决方案1】:
Palabra primeraPalabra(0,"");
Palabra ultimaPalabra(0, "");
Palabra palabraTemp(0, "");

这在您的头文件中定义并实例化了三个对象。每个包含此头文件的.cpp 都将定义这三个对象。你显然有多个.cpp 文件;所以这是你的编译器和链接器最终向你咆哮的多重定义错误。

#include 在逻辑上等同于将头文件的内容 逐字 插入到.cpp 文件中。从头文件中删除这些定义,并手动将它们添加到包含此头文件的每个.cpp 文件中,您将得到相同的错误。

您需要在头文件中使用extern 关键字声明这些对象。然后,在您的.cpp 文件中定义这些对象正好一个,无论您觉得哪个更多适合定义它们。

你的 C++ 书应该有很多这样的例子,以及如何使用 extern 关键字。

附:那个using namespace std;,在你的头文件中也不少,is going to give you a world of hurt迟早。你需要摆脱它。你解释说,因为你刚刚开始学习 C++,所以这是你避免养成坏习惯的最佳时机。只需忘记“使用命名空间标准;”目前存在于 C++ 中,直到你完全理解它的作用。一开始可能看起来很烦人,但用不了多久,您甚至不会有意识地意识到您的手指会在 C++ 库中的每个模板、类和函数之前自动输入std::。

【讨论】:

    【解决方案2】:

    如果您想创建对象的实例,则应在需要的地方进行。现在让我们假设这将在 main.js 中完成。

    创建了一个名为:main.cpp 的新文件

    里面有以下内容:

    #include "Palabra.h"
    int main() 
    {
     Palabra palabra_one(0, ""); 
     return 0; 
    }
    

    【讨论】:

    • 请注意,您有 3 个 Palabra 类的实例化,它们都在构造函数中传递相同的东西。如果您的目标是让它们成为默认值,请创建一个新的构造函数 Palabra() { p_id = 0; p_nombre = ""; }
    【解决方案3】:
    Palabra primeraPalabra(0,"");
    Palabra ultimaPalabra(0, "");
    Palabra palabraTemp(0, "");
    

    给定头文件的一个关键问题可以在以下几行中看到。您正在一个头文件

    中创建一个类的 3 个实例

    首先,我们应该问自己:“什么是头文件?” 假设您有许多函数声明,并且您的程序有许多不同的类和结构定义。好吧,一种选择是将它们全部放在 .cpp 文件中。好吧,那会很混乱,代码也不会那么模块化。我们应该问自己的问题是:“我们如何将我们的函数和方法定义和声明以及类和结构定义分离到不同且唯一的文件中?”

    不出所料,头文件可以帮助我们。

    假设您有 2 个类 A 和 B,并且您希望将它们的声明和定义分开到不同的文件中。 这是执行此操作的常规方法: A.h - 包含仅与 A 相关的声明的文件 A.cpp - 一个文件,其中包含 A.h 中声明的函数和方法的实现 B.h - 一个仅包含与 A 相关的声明的文件** B.cpp - 一个文件,其中包含 B.h

    中声明的函数和方法的实现

    有人可能会问:“您将如何使用头文件中声明的函数和方法?” 为了在源代码中包含头文件,您可以在 C/C++ 代码上方键入以下内容

    #include "filename.h"
    

    ************** 额外说明 ************** 在有人在 cmets 中对我大喊大叫之前 - 是的,模板函数实现应该在头文件中,而不是在 cpp 文件中 如果您不知道模板是什么 - https://en.wikipedia.org/wiki/Template_(C%2B%2B)(额外材料) 但这是一个完全不同的话题 ************** 额外说明**************

    那将如何编译????????? 好吧,在编译和最终可执行文件之间有一个称为链接的中间阶段。 linker 负责组合所有指定的使用的头文件;您可以在此处阅读有关链接过程的更多信息:https://en.wikipedia.org/wiki/Linker_(computing)

    结论——代码中的问题

    您实际上是在头文件中编写了用于创建类的3个实例的行。 这些行完全不合适,可能是偶然写在那里的,但是,由于您指定您对标题的工作方式不熟悉,这是一个带有一些流行词的一般性介绍,您可以随意使用谷歌搜索。有什么问题可以在cmets问我!

    【讨论】:

    • 这是我的第一个 stackoverflow 答案,所以请提出改进​​意见:)
    猜你喜欢
    • 2013-07-25
    • 2011-08-13
    • 2011-12-07
    • 2011-04-06
    • 2016-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-17
    相关资源
    最近更新 更多