前置声明和头文件之间的关系 问题

出现这些问题的原因是 ORB_SLAM3::MultiGraph 被前置声明了,但在使用的时候,编译器并没有看到 MultiGraph 类的完整定义。前置声明只能用于指针和引用,但如果要访问其成员函数或变量,必须包含完整的类定义。

解决方案步骤:

  1. 头文件依赖问题:由于你有多线程并且不同头文件相互包含,直接包含头文件可能会造成编译错误。最常见的解决办法是减少头文件的相互依赖,同时确保所有需要使用的类都已经定义好。

  2. 将需要访问 MultiGraph 类成员的代码移动到包含 MultiGraph 类定义的地方

    • 在头文件中前置声明 MultiGraph,以便在头文件中使用指针或引用。
    • 在实现文件 (.cpp) 中 #include "MultiGraph.h",以便在实现文件中使用类的成员。

具体修改方法

1. 确保在 map.h 中只使用前置声明

map.h 中,你只需要前置声明 MultiGraph,因为这里只是保存 MultiGraph* 的指针,不需要访问它的成员。

// map.h
#ifndef MAP_H
#define MAP_H

namespace ORB_SLAM3 {
    class MultiGraph;  // 前置声明 MultiGraph

    class Map {
    public:
        MultiGraph* mGlobalMapGraph;  // 指向 MultiGraph 的指针
        bool isGlobalInitialized = false;

        void AddGlobalMapGraph();
        void addEdges(MultiGraph *graph, bool isGlobalMap = false);

        // 其他成员函数和变量
    };

}  // namespace ORB_SLAM3

#endif  // MAP_H
2. 在 map.cc 中包含 MultiGraph.h

由于你在 .cpp 文件中使用了 MultiGraph 的成员(例如 addNodeaddEdge),你需要包含 MultiGraph.h,以便访问 MultiGraph 的完整定义。

// map.cc
#include "Map.h"
#include "MultiGraph.h"  // 需要包含 MultiGraph 的完整定义

namespace ORB_SLAM3 {

void Map::AddGlobalMapGraph() {
    if (mvObjectMap.size() > 0) {
        for (int i = 0; i < mvObjectMap.size(); i++) {
            GraphNode node_3D;
            node_3D.obj3D = mvObjectMap[i];
            mGlobalMapGraph->addNode(node_3D);  // 使用 addNode 成员函数
        }
        this->addEdges(mGlobalMapGraph, true);
        isGlobalInitialized = true;
    }
}

void Map::addEdges(MultiGraph *graph, bool isGlobalMap) {
    for (size_t i = 0; i < graph->nodes.size(); ++i) {
        for (size_t j = i + 1; j < graph->nodes.size(); ++j) {
            float classSim = calculateClassSimilarity(graph->nodes[i].obj3D->mnClass, graph->nodes[j].obj3D->mnClass);
            if (classSim > 0) {
                graph->addEdge(i, j, ORB_SLAM3::EdgeType::CATEGORY_EDGE, classSim);
            }
            // 继续其他边的计算和添加...
        }
    }
}

}  // namespace ORB_SLAM3
3. 确保 MultiGraph.h 定义完整的 MultiGraph

MultiGraph.h 文件中,确保你已经完整定义了 MultiGraph 类,包括它的成员函数和结构体。

// MultiGraph.h
#ifndef MULTIGRAPH_H
#define MULTIGRAPH_H

#include <vector>
#include <map>
#include "Object.h"  // 假设你需要访问 Object_2D 和 Object_Map 类

namespace ORB_SLAM3 {

class Object_2D;
class Object_Map;

enum EdgeType {
    CATEGORY_EDGE,
    COLOR_EDGE,
    MASK_SIMILARITY_EDGE,
    BBOX_OVERLAP_EDGE,
    HISTORY_ASSOCIATION_EDGE
};

struct GraphNode {
    int id;
    Object_2D* obj2D;
    Object_Map* obj3D;
    std::map<int, std::map<EdgeType, float>> edges;
};

class MultiGraph {
public:
    std::vector<GraphNode> nodes;

    void addNode(const GraphNode& node) {
        nodes.push_back(node);
    }

    void addEdge(int node1, int node2, EdgeType edgeType, float weight) {
        nodes[node1].edges[node2][edgeType] = weight;
        nodes[node2].edges[node1][edgeType] = weight;
    }
};

}  // namespace ORB_SLAM3

#endif  // MULTIGRAPH_H

总结

  1. 前置声明:在头文件中,尽可能只做前置声明,减少依赖。
  2. 包含完整定义:在 .cpp 文件中包含完整的定义 (#include "MultiGraph.h"),确保可以访问类的成员。
  3. 分离依赖:通过前置声明和头文件包含分离类的依赖,避免相互依赖引起的问题。

这样可以确保你在头文件中可以声明指针类型,并在 .cpp 文件中正常使用类的完整定义,不会再遇到“incomplete type”的错误。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值