对放置的地图值的引用需要定义类

时间:2016-04-16 15:55:05

标签: c++

我需要改变我在正在处理的大型项目中包含标题的方式。我能够用较小的单个程序模拟我目前得到的错误。

举例来说,以下编译:

#include <map>

class C;

class A {
public:
    C& add();
    std::map<int,C> Cmap;
    void dosomethingwithC();
};

class B {
public:
    A& add();
    std::map<int,A> Amap;
};

class C {
public:
    B& add();
    std::map<int,B> Bmap;
};

int main()
{
    C c;
    auto& emplacedB = c.add();
    auto& emplacedA = emplacedB.add();
    auto& emplacedC = emplacedA.add();
    emplacedC.add();
    return 0;
}

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

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

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

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

但是,如果我将A的函数定义移近A,则以下内容不会编译:

#include <map>

class C;

class A {
public:
    C& add();
    std::map<int,C> Cmap;
    void dosomethingwithC();
};

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

class B {
public:
    A& add();
    std::map<int,A> Amap;
};

class C {
public:
    B& add();
    std::map<int,B> Bmap;
};

int main()
{
    C c;
    auto& emplacedB = c.add();
    auto& emplacedA = emplacedB.add();
    auto& emplacedC = emplacedA.add();
    emplacedC.add();
    return 0;
}

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

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

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

即使宣布class C,我也会收到错误消息。该错误说明std::pair使用 undefined class C

构造标题的正确方法是什么,包括进行编译?

1 个答案:

答案 0 :(得分:1)

方法

  • 所有声明必须放在标题中
  • 所有定义都会进入.cpp文件。
  • 没有标题包含彼此。

在这个特定实例中,如果所有.cpp文件都包含所有声明,那么关于缺失定义的错误(对于std::pair,作为std::map的一部分)就会消失。 (A需要C,但C需要B)

因此即使错误是针对缺失的定义,也可以通过包含声明来解决。我不确定为什么会发布separate question

解决方案

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" // also required here
#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;
}

Main.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;
}