循环依赖 c++ 因前向声明而失败
Circular dependency c++ fails with forward decleration
我有两个 classes,MeassurementIteration 和 Meassurementset。 meassurementIteration 有一个集合向量,一个集合有一个指向迭代的指针。
测量迭代
#pragma once
#include <vector>
#include "MeassurementSetRepo.h"
#include "MeassurementSet.h"
class MeassurementIteration
{
public:
MeassurementIteration(const int id, const long start, const long end, const bool active)
: id_(id)
, start_(start)
, end_(end)
, active_(active)
{}
MeassurementIteration();
~MeassurementIteration() = default;
std::vector<MeassurementSet>& getMeasurementSet()
{
/** Magic **/
return this->msSets_;
}
private:
const int id_;
const long start_;
long end_;
bool active_;
MeassurementSetRepo mssetRepo;
std::vector<MeassurementSet> msSets_;
};
测量集
#pragma once
#include <string>
#include <memory>
#include "MeassurementIterationRepo.h"
class MeassurementIteration;
class MeassurementSet
{
public:
MeassurementSet(const int id, const std::string & way, const int it_id)
: id_(id)
, msWay_(way)
, MeassurementIteration_Id_(it_id)
{
msit_ = nullptr;
}
~MeassurementSet()
{
delete msit_;
}
MeassurementIteration& getMSIteration()
{
if (this->msit_ == nullptr)
{
/** Magic sets msit **/
}
return *msit_;
}
private:
int id_;
const std::string msWay_;
const int MeassurementIteration_Id_;
MeassurementIterationRepo msitRepo_;
MeassurementIteration * msit_;
};
我不明白为什么我在这里得到循环依赖。当我阅读其他帖子时,这似乎是这样做的方法。
有人可以向我解释一下我做错了什么吗?
更新:问题似乎是由于使用了相反的 classes 存储库。为了说明,请参见此图。
我该如何解决这个依赖地狱?
有一项重要的原则需要您学习,那就是接口。
我的想法是,当我想使用您的 class 之一时,我只想知道 class 的功能。我不需要知道的是它是如何实现的,也就是实现细节。
这就是 C++ 将文件分为 header 文件和源文件的原因之一。 Header 文件应该包含它的作用,源文件应该包含它是如何完成的。人们甚至可以争论一种新格式,其中 header 文件仅包含 public 声明(即没有私有成员变量、私有辅助方法等)。
使用它会对您的事业有所帮助。乍一看我没有看到任何有问题的行,但可能是 IterationRepo includes Iteration includes Set includes IterationRepo.
接口如何帮助您:在 header 中,只声明,不实现任何东西(有些人用 one-liners 这样做,但我建议也不要那样做)。仅 Forward-declare。包含在源文件中。这样你就不能有循环依赖了。
(当然,对于成员变量类型来说,这个规则被打破了——如果 A 有一个成员变量 B,它需要知道 B 是什么才能知道它的大小,因此它需要将它包含在 header.)
我有两个 classes,MeassurementIteration 和 Meassurementset。 meassurementIteration 有一个集合向量,一个集合有一个指向迭代的指针。
测量迭代
#pragma once
#include <vector>
#include "MeassurementSetRepo.h"
#include "MeassurementSet.h"
class MeassurementIteration
{
public:
MeassurementIteration(const int id, const long start, const long end, const bool active)
: id_(id)
, start_(start)
, end_(end)
, active_(active)
{}
MeassurementIteration();
~MeassurementIteration() = default;
std::vector<MeassurementSet>& getMeasurementSet()
{
/** Magic **/
return this->msSets_;
}
private:
const int id_;
const long start_;
long end_;
bool active_;
MeassurementSetRepo mssetRepo;
std::vector<MeassurementSet> msSets_;
};
测量集
#pragma once
#include <string>
#include <memory>
#include "MeassurementIterationRepo.h"
class MeassurementIteration;
class MeassurementSet
{
public:
MeassurementSet(const int id, const std::string & way, const int it_id)
: id_(id)
, msWay_(way)
, MeassurementIteration_Id_(it_id)
{
msit_ = nullptr;
}
~MeassurementSet()
{
delete msit_;
}
MeassurementIteration& getMSIteration()
{
if (this->msit_ == nullptr)
{
/** Magic sets msit **/
}
return *msit_;
}
private:
int id_;
const std::string msWay_;
const int MeassurementIteration_Id_;
MeassurementIterationRepo msitRepo_;
MeassurementIteration * msit_;
};
我不明白为什么我在这里得到循环依赖。当我阅读其他帖子时,这似乎是这样做的方法。 有人可以向我解释一下我做错了什么吗?
更新:问题似乎是由于使用了相反的 classes 存储库。为了说明,请参见此图。
我该如何解决这个依赖地狱?
有一项重要的原则需要您学习,那就是接口。
我的想法是,当我想使用您的 class 之一时,我只想知道 class 的功能。我不需要知道的是它是如何实现的,也就是实现细节。
这就是 C++ 将文件分为 header 文件和源文件的原因之一。 Header 文件应该包含它的作用,源文件应该包含它是如何完成的。人们甚至可以争论一种新格式,其中 header 文件仅包含 public 声明(即没有私有成员变量、私有辅助方法等)。
使用它会对您的事业有所帮助。乍一看我没有看到任何有问题的行,但可能是 IterationRepo includes Iteration includes Set includes IterationRepo.
接口如何帮助您:在 header 中,只声明,不实现任何东西(有些人用 one-liners 这样做,但我建议也不要那样做)。仅 Forward-declare。包含在源文件中。这样你就不能有循环依赖了。
(当然,对于成员变量类型来说,这个规则被打破了——如果 A 有一个成员变量 B,它需要知道 B 是什么才能知道它的大小,因此它需要将它包含在 header.)