缺少定义错误可以通过只包含声明来解决

Missing definition error is solved by including only a declaration

本文关键字:包含 声明 解决 可以通过 定义 错误      更新时间:2023-10-16

为什么包含声明可以解决缺少的定义错误?这与前面的一个问题有关。

在下面的一组文件中,我很惊讶为一个未使用的类寻找定义,然后当我只包含程序编译的类的声明时。

我已经为必须添加的include添加了注释,但不明白为什么在那些特定的.cpp文件中需要它们。

A.h

#ifndef A_h
#define A_h
#include <map>
class C;
class A {
public:
    C& add();
    std::map<int,C> Cmap;
    void dosomethingwithC();
};
#endif

B.h

#ifndef B_h
#define B_h
#include <map>
class A;
class B {
public:
    A& add();
    std::map<int,A> Amap;
};
#endif

C.h

#ifndef C_h
#define C_h
#include <map>
class B;
class C {
public:
    B& add();
    std::map<int,B> Bmap;
};
#endif

A.cpp

#include "A.h"
#include "B.h"// Required here, but B isn't used in this file.
              // Without B.h the error is
              // error C2079: 'std::pair<const _Kty,_Ty>::second' uses undefined class 'B'
              // But B.h only includes the declaration, not the definition
#include "C.h"
C& A::add()
{
    auto emplace_results = Cmap.emplace(std::piecewise_construct,
        std::forward_as_tuple(3),
        std::forward_as_tuple());
    auto pair_iterator = emplace_results.first;
    auto& emplaced_pair = *pair_iterator;
    auto& map_value = emplaced_pair.second;
    return map_value;
}

void A::dosomethingwithC()
{
    Cmap[3].add();
}

B.cpp

#include "A.h"
#include "B.h"
#include "C.h" // also required here
A& B::add()
{
    auto emplace_results = Amap.emplace(std::piecewise_construct,
        std::forward_as_tuple(3),
        std::forward_as_tuple());
    auto pair_iterator = emplace_results.first;
    auto& emplaced_pair = *pair_iterator;
    auto& map_value = emplaced_pair.second;
    return map_value;;
}

C.cpp

#include "A.h" // also required here
#include "B.h"
#include "C.h"
B& C::add()
{
    auto emplace_results = Bmap.emplace(std::piecewise_construct,
        std::forward_as_tuple(3),
        std::forward_as_tuple());
    auto pair_iterator = emplace_results.first;
    //auto& emplaced_pair = *pair_iterator;
    std::pair<const int,B>& emplaced_pair = *pair_iterator;
    auto& map_value = emplaced_pair.second;
    return map_value;
}

主要.cpp

#include "A.h"
#include "B.h"
#include "C.h"
int main()
{
    C c;
    auto& emplacedB = c.add();
    auto& emplacedA = emplacedB.add();
    auto& emplacedC = emplacedA.add();
    emplacedC.add();
    return 0;
}
  1. B是在C.cpp中使用的。它用于定义C.的成员变量

  2. B.hpp不包含类B(可能是class B;)的声明。它包含它(但不包含其成员)的定义

STL容器中不允许不完整类型(正向声明),尽管boost容器允许它。我认为如果包含所需的头文件而不是正向声明,它会解决这个问题。