【问题标题】:header guard conundrum - already defined in .obj problem标头保护难题 - 已在 .obj 问题中定义
【发布时间】:2011-09-23 11:18:28
【问题描述】:

我有一个类 (A),它必须包含两个文件,类 X 和类 Y。不幸的是,类 Y 还需要在其头文件中包含类 X,因为构造函数将指向类 X 类型的指针作为参数.

潜在的问题是会出现链接器错误?因为 A 类现在有两个 X 类的副本,一个它需要使用,一个来自 Y 类。这就是标题保护没有用的情况。我的问题是 - 这纯粹是一个结构性问题还是有办法解决这个问题?

我真的不希望在类 Y 的头文件中包含任何东西,以防我想在其他任何东西中包含它,但由于函数原型的原因,有必要吗?

【问题讨论】:

  • 这应该不是问题,只要您没有在头文件中定义任何非内联函数。你能发布一些有代表性的代码吗?
  • 其实我很抱歉,我认为错误来自其他地方。尽管如此,这还是值得学习的。那么只要头文件只包含原型,就可以包含多个相同的没有任何问题?
  • 您可以拥有类定义以及成员函数定义,只要它们被内联到类主体本身,例如:class X { int foo() { return 1; } };。这不好:class X { int foo(); }; int X::foo() { return 1; }.
  • 刚刚对问题进行了小幅编辑,因此它对社区更有用 - 现在是理论上的问题,但内容相同。

标签: c++


【解决方案1】:

如果您有以下情况:

X.h

#ifndef X_H__
#define X_H__

class X
{
public:
    int foo() { return 1; }
};

#endif

Y.h

#ifndef Y_H__
#define Y_H__

#include "X.h"

class Y
{
public:
    Y(X *pX) { myval = pX->foo(); }
    int myval;
};

#endif

something.cpp

#include "X.h"

...

something_else.cpp

#include "Y.h"

...

那么应该没有问题。

但是,如果 X.h 看起来像这样:

#ifndef X_H__
#define X_H__

class X
{
public:
    int foo();
};

int X::foo() { return 1; }

#endif

那么当您尝试链接something.cppsomething_else.cpp 时,您确实会收到链接器错误。 X::foo 将被非内联定义为两个单独的翻译单元

【讨论】:

  • 解决方法...?没有人愿意在类中定义方法。
  • @TomášZato:解决方法?有两种选择;在类定义中定义成员函数“inline”,或者在单独的 .cpp 文件中定义它。
  • 这为我节省了很多时间。但我仍然不明白为什么会这样。在我的代码中,我有一个没有类的文件 X.h,只有两个辅助方法。现在我将它们放在一个类中,使它们成为静态的并且它可以工作。谁能解释一下?
  • @TomášZato :问题不在于方法的定义在类中(“...在标题中的类声明。”会更准确)。问题在于方法的定义在标题中。 :) 它必须是内联的。
【解决方案2】:

您可以在 Y 标头中使用声明。

class X;

由于您只使用指向 X 的指针,编译器不需要知道它的定义。

【讨论】:

    猜你喜欢
    • 2016-01-05
    • 2021-05-22
    • 1970-01-01
    • 1970-01-01
    • 2020-04-20
    • 2014-10-25
    • 2012-01-22
    • 1970-01-01
    • 2014-11-08
    相关资源
    最近更新 更多