0

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

课程

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

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

// a.h
#pragma once

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

阿尔法实施:

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

伽玛实现:

// 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 的实现文件包含“gh”和“bh”,其中每个包含“ah”和“a.cpp”,因此包含“a.cpp”,因为它没有标头保护。

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

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

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

认真地感谢任何指导!

4

3 回答 3

1

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

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

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

于 2013-05-22T01:31:13.987 回答
0

停止#include .cpp 文件。.h 是您最需要的,有时只需一个前向声明就足够了。 这里这里这里是对它们服务目的的体面描述。

于 2013-05-22T01:35:15.680 回答
0

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

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

您在这里不需要前向声明(尽管您可以改用它)

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

于 2013-05-22T01:36:50.867 回答