2

I am trying to organise my code into a more OOP style with each class taking on its own header and cpp file. This is my tree in the package folder in the workspace

- CMakeLists.txt
- include
- - Master_Thread.h
- - Entry.h
- - ROS_Topic_Thread.h
- src
- - pcl_ros_init.cpp
- - archive
- - - pcl_ros_not_updated.cpp
- - - pc_ros_old2.cpp
- - - thread.cpp
- - - pcl_ros_old.cpp
- package.xml

I haven't placed the classes definition in the cpp files respectively, i have placed them all with the main code(pcl_ros_init.cpp) for the time being. My classes have some slight dependency on one another, for example Master_Thread class uses ROS_Topic_Thread in its declaration and right now, Cmake is able to find the include files but within the header files like Master_Thread.h, it is unable to find the class signature of ROS_Topic_Thread as such pcl_ros_custom/include/Master_Thread.h:38:36: error: ‘ROS_Topic_Thread’ has not been declared

This is my CMakeLists.txt

cmake_minimum_required(VERSION 3.0.2)
project(pcl_ros_custom)

find_package(catkin REQUIRED COMPONENTS
roscpp
pcl_conversions
pcl_ros)

catkin_package(
INCLUDE_DIRS
CATKIN_DEPENDS roscpp
           pcl_conversions
           pcl_ros
)

include_directories(
include
${catkin_INCLUDE_DIRS}/include/**
)

add_executable(pcl_ros_init src/pcl_ros_init.cpp)
target_link_libraries(pcl_ros_init 
            ${catkin_LIBRARIES} ${roslib_LIBRARIES} ${PCL_LIBRARIES} )

These are 2 of the header files

#ifndef MASTER_THREAD_H
#define MASTER_THREAD_H
#include <ros/ros.h>
#include <pcl_conversions/pcl_conversions.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <sensor_msgs/PointCloud2.h>

#include <thread>
#include <mutex>
#include <chrono>
#include <functional>
#include <utility>
#include <string>

//include custom classes
#include "ROS_Topic_Thread.h"
#include "ClusteringBenchmarkEntry.h"


namespace OCB
{
    class Master_Thread
{
    private:
    std::atomic<bool> mKillswitch;
    std::vector<sensor_msgs::PointCloud2ConstPtr> mMasterbuffer1, mMasterbuffer2, mMasterbuffer3, mMasterbuffer4, mMergedPointCloud2Ptr_buffer;
    public:
    Master_Thread();
    void transfer_to_master_buffer(ROS_Topic_Thread&t1,ROS_Topic_Thread&t2, ROS_Topic_Thread&t3, ROS_Topic_Thread&t4 );
    
    void process_buffer();
    void setkillswitch();
};

} 
#endif
#ifndef ROS_TOPIC_THREAD_H
#define ROS_TOPIC_THREAD_H

#include <ros/ros.h>
#include <pcl_conversions/pcl_conversions.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <sensor_msgs/PointCloud2.h>

#include <thread>
#include <mutex>
#include <chrono>
#include <functional>
#include <utility>
#include <string>


#include "Master_Thread.h"
#include "ClusteringBenchmarkEntry.h"

namespace OCB
{
class ROS_Topic_Thread
{
    private:
    ros::Subscriber mSub;

    // Topic
    const std::string mSUB_TOPIC;

    //buffer
    std::vector<sensor_msgs::PointCloud2ConstPtr> mThreadbuffer;
    
    std::mutex mMutex;

    public:
    ROS_Topic_Thread()= delete;
    ROS_Topic_Thread(ros::NodeHandle* nodehandle, const std::string& SUBTOPIC, ClusteringBenchmarkEntry* entry);
  
    void callback(const sensor_msgs::PointCloud2ConstPtr& sub_ptr);
    friend class Master_Thread;

};

} //namespace close scope

#endif //for ROS_TOPIC_THREAD_H

Where am i going wrong?

EDIT

This is a really good link which clears up most of my header files organisation in C++ which on top of the answers helps me get project building to go smoothly. Hope it helps whoever is reading this.

Iberico
  • 162
  • 2
  • 15
  • We will need to see the header files, do you include the necessary items from each header file? – Fantastic Mr Fox Jun 08 '21 at 09:34
  • @FantasticMrFox I have included some of the headers. I overused #include but it shouldn't be the source of the problem i think. – Iberico Jun 08 '21 at 11:06
  • 1
    @Iberico I guess the problem is that you have a **circular dependency**: `ROS_TOPIC_THREAD_H` includes `MASTER_THREAD_H` and vice versa. I guess you will need to forward-declare one of the classes (see [e.g. here](https://stackoverflow.com/questions/625799/resolve-build-errors-due-to-circular-dependency-amongst-classes)). – 2b-t Jun 08 '21 at 12:13

1 Answers1

1

In essence you don't need to include either header into the other. This fixes the circular includes. In ROS_Topic_Thread.h, friend class Master_Thread; already forward declares Mater_Thread, so you don't need the Master_Thread.h header. In Master_Thread.h, you can also forward declare class ROS_Topic_Thread; before the declaration of the Master_Thread class, since you only use references to ROS_Topic_Thread in the transfer_to_master_buffer method.

#ifndef MASTER_THREAD_H
#define MASTER_THREAD_H
#include <ros/ros.h>
#include <pcl_conversions/pcl_conversions.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <sensor_msgs/PointCloud2.h>

#include <thread>
#include <mutex>
#include <chrono>
#include <functional>
#include <utility>
#include <string>

//include custom classes
#include "ClusteringBenchmarkEntry.h"


namespace OCB
{
    class ROS_Topic_Thread;
    class Master_Thread
{
    private:
    std::atomic<bool> mKillswitch;
    std::vector<sensor_msgs::PointCloud2ConstPtr> mMasterbuffer1, mMasterbuffer2, mMasterbuffer3, mMasterbuffer4, mMergedPointCloud2Ptr_buffer;
    public:
    Master_Thread();
    void transfer_to_master_buffer(ROS_Topic_Thread&t1,ROS_Topic_Thread&t2, ROS_Topic_Thread&t3, ROS_Topic_Thread&t4 );
    
    void process_buffer();
    void setkillswitch();
};

} 
#endif
#ifndef ROS_TOPIC_THREAD_H
#define ROS_TOPIC_THREAD_H

#include <ros/ros.h>
#include <pcl_conversions/pcl_conversions.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <sensor_msgs/PointCloud2.h>

#include <thread>
#include <mutex>
#include <chrono>
#include <functional>
#include <utility>
#include <string>

#include "ClusteringBenchmarkEntry.h"

namespace OCB
{
class ROS_Topic_Thread
{
    private:
    ros::Subscriber mSub;

    // Topic
    const std::string mSUB_TOPIC;

    //buffer
    std::vector<sensor_msgs::PointCloud2ConstPtr> mThreadbuffer;
    
    std::mutex mMutex;

    public:
    ROS_Topic_Thread()= delete;
    ROS_Topic_Thread(ros::NodeHandle* nodehandle, const std::string& SUBTOPIC, ClusteringBenchmarkEntry* entry);
  
    void callback(const sensor_msgs::PointCloud2ConstPtr& sub_ptr);
    friend class Master_Thread;

};

} //namespace close scope

#endif //for ROS_TOPIC_THREAD_H
mo_al_
  • 561
  • 4
  • 9