【问题标题】:cyclic includes, how can I resolve this without changing class hierarchy循环包含,如何在不更改类层次结构的情况下解决此问题
【发布时间】:2011-10-16 02:12:41
【问题描述】:
            Animal
               |
           Mammal
               / \
      TwoLegged - FourLegged
         /           \
        Human      Lion

我有这个类层次结构,每个类都在它自己的标题中定义。现在,当我同时包含两者时 Human.h 和 Lion.h 在同一个地方,我得到一个哺乳动物重新定义错误。

 error C2011: 'Mammal' : 'class' type redefinition

这是因为 Mammal.h 包含在 TwoLegged 和 OneLegged 类中。

我不确定如何解决头文件中的这种循环依赖,因为我无法更改类层次结构。

有人愿意帮忙吗?

编辑:

哺乳动物头

#ifndef MAMMAL_H
#define MAMNAL_H

#include "stdafx.h"
#include "Animal.h"

class Mammal : public Animal
{
public:
    Mammal::Mammal();
    virtual Mammal::~Mammal();

    std::string mammal_name();
    int mammal_age();
    int mammal_expectedlifedays();
    bool mammal_hunter();
    int mammal_power();
    int mammal_birthrate();
    bool mammal_alive();

protected:
    Mammal::Mammal(const std::string& mname, int mexpectedlifedays, int mage, bool mhunter, int mpower, int mbirthrate, bool malive) : Animal(mname, mexpectedlifedays, mage,mhunter,  mpower, mbirthrate, malive)
    {}
private:
};

#endif

编译器给出的错误:

error C2011: 'Mammal' : 'class' type redefinition
see declaration of 'Mammal'

error C2504: 'Mammal' : base class undefined
error C2614: 'TwoLegged' : illegal member initialization: 'Mammal' is not a base or member

注意:这不是家庭作业,否则我会这样标记它。

【问题讨论】:

  • 你的头文件有编译保护吗? #ifndef /#def/ #endif
  • 你在使用包含防护吗?
  • @John:是的,我有那些编译守卫。
  • @Tony:Mammal.h 中的包含保护一定有问题,或者您实际上在某处重新定义了 class Mammal!按照您描述问题的方式,没有循环包含(例如,如果Mammal.h 包含Lion.h,就会出现这种情况)。
  • @Tony:只要你有包含警卫,这不是问题(这正是它们的用途)。而且它与循环无关,因为Mammal 独立于LionHuman

标签: c++ class include


【解决方案1】:
#pragma once

将其添加到所有头文件的最顶部。

但是,请记住,即使编译器很好地支持它,它也不是标准。

【讨论】:

  • 更好地使用#ifndef /#def/ #endif!
  • 不太支持。众所周知,GCC 没有它。
  • 当然,您必须检查您正在使用的编译器。但如果你的编译器支持它,那么它比包含保护更简洁,更不容易出错。
  • @rodrigo 从 gcc 3.4 开始支持它。见gcc.gnu.org/gcc-3.4/changes.html
  • 伙计们,这个讨论是题外话。很可能 OP 忘记/输入错误包括警卫(无论哪种),这个答案只是部分帮助。
【解决方案2】:

您需要使用包含防护。典型的形式是:

#ifndef NAME_OF_HEADER_H
#define NAME_OF_HEADER_H

// Rest of header code here.

#endif

由于 C++ 中的 #include 只是复制粘贴当前文件中的文本,如果相同的标题被包含两次,那么该文本将导致重复的类定义。包含保护的作用是防止多次包含同一个标头。

编辑:问题是您检查MAMMAL_H 的定义,然后定义MAMNAL_H(注意定义版本中的N)。正是出于这个原因,我总是复制粘贴来生成我的包含守卫。

【讨论】:

  • @Tony The Tiger:你确定或者可以重新检查所有文件是否都已经到位并且当然正确!
  • @Tony The Tiger 在这种情况下,我认为我们需要看到一个为您展示问题的最小示例。
【解决方案3】:

我猜你忘了包括警卫。按照 John 的建议使用 #ifndef /#ifdef/ #endif。

【讨论】:

  • -1 只是猜测,然后只是参考别人的答案。这个答案对已经给出的答案没有任何帮助。
  • 这很公平!不是故意的。对不起,伙计们。
【解决方案4】:
#ifndef MAMMAL_H
#define MAMMAL_H



... definition of mammal


#endif

【讨论】:

    猜你喜欢
    • 2020-08-17
    • 2017-05-23
    • 2023-02-25
    • 2020-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多