【问题标题】:C++ proper way for solve this inheritence include issue "already has a body"?解决此继承的 C++ 正确方法包括“已经有主体”的问题?
【发布时间】:2013-05-22 09:41:41
【问题描述】:

嘿嘿,我有一个关于我在 C++ 中遇到的这个问题的问题。我是 C++ 和学习的新手。我有面向对象编程的经验,所以我正在寻找正确的方法来解决这个问题,以及为什么应该这样做。

我已将每个类分成接口头文件和实现cpp文件。

第一个类“Alpha”是我的基类:

// a.h
#pragma once

class Alpha
{
public:
    virtual void myFunction();
};

Alpha 实现:

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

void Alpha::myFunction()
{
    std::cout << "Class Alpha myFunction" << std::endl;
}

然后我有一个子类“Beta”:

// b.h
#pragma once
#include "a.h"
#include "a.cpp"

class Beta : public Alpha
{
public:
    virtual void myFunction();
};

测试版实施:

// b.cpp
#include <iostream>
#include "b.h"

void Beta::myFunction()
{
    std::cout << "Class Beta myFunction" << std::endl;
}

然后我就有了一个名为“Gamma”的管理器类。

// g.h
#pragma once
#include <vector>
#include "a.h"
#include "a.cpp"

class Gamma
{
public:
    void run();
    std::vector<std::shared_ptr<Alpha>> alphaCollection;
};

Gamma 实现:

// g.cpp
#include "g.h"
#include "b.h"
#include "b.cpp"

void Gamma::run()
{
    Beta localBeta;

    alphaCollection.push_back(std::make_shared<Beta>(localBeta));

    // example usage
    alphaCollection.at(0)->myFunction();
}

最后是我的主要内容:

#include "g.h";
#include "g.cpp";

int main()
{
    Gamma objectG;
    objectG.run();
}

我为什么要这样做

所有这些的目的是我想要在我的管理器中使用基类 Alpha 的向量,然后我可以在其中插入不同数量的基类对象的元素。

我使用 Beta 作为派生类的示例,但在实际实现中会有更多派生类,例如 Charlie、Delta 等。

目标是我的 Manager 类 Gamma 将能够将向量元素作为 Alpha 对象进行操作,并且每个子类都执行自己的行为。

问题

我无法编译上面的示例,因为 Gamma 的实现文件包含“g.h”和“b.h”,每个都包含“a.h”和“a.cpp”,因此包含“a.cpp”,因为它没有标头保护.

  • 错误 C2084:函数 'void Alpha::myFunction(void)' 已经有一个主体 a.cpp
  • 错误 C2264:“Alpha::myFunction”:函数定义或声明中的错误;函数未调用 g.cpp

我已经阅读了关于如何使用包含的不同意见,总体而言,我只是觉得在理解组织代码以防止他的正确方法方面是一个菜鸟。

  1. 我是不是很杂乱无章?
  2. 实现文件是否也应使用​​标头保护?
  3. 我应该使用前向声明吗?如果有怎么办?
  4. 希望实现包含子类包含而标题仅包含基类包含,我疯了吗?

非常感谢任何指导!

【问题讨论】:

  • 你只需要包含头文件,不需要.cpp文件。是的,使用标头保护是个好主意(在头文件中,而不是 .cpp 文件中)

标签: c++ inheritance include dependencies header-files


【解决方案1】:

不要#include cpp 文件。这不是必需的,这就是导致问题的原因。

#pragma once 与包含保护相同 - 但请记住它不是可移植的 - 它特定于您当前的编译器。

你不应该在你的 cpp 文件中包含守卫,因为你不应该#include他们。

【讨论】:

  • 谢谢,我将换掉标题保护并停止包含 noobish cpp。万岁
【解决方案2】:

您只需要包含头文件,而不是 .cpp 文件。

您不想在 .cpp 文件中使用标头保护。

这里不需要前向声明(尽管你可以使用它)

您的实现不包括“子类包含”,它们包括定义其接口的头文件。您对 a.h 的包含在 g.h 中是正确的。

【讨论】:

    【解决方案3】:

    停止#包括 .cpp 文件。 .h 是您最需要的,有时只需一个前向声明就足够了。 Hereherehere 很好地描述了它们的用途。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-10
      • 1970-01-01
      相关资源
      最近更新 更多