3

I am trying to follow the PIMPL idiom for C++. I have thus created a class AgeDetect which will be my user facing interface, and AgeDetectImpl which contains all the implementation. I am forward declaring AgeDetectImpl and using an std::unique_ptr to store it as a private member of AgeDetect. I followed the instructions from this question and have implemented a destructor so I am not sure what the issue is.

AgeDetect.h

#ifndef AGE_DETECT_H
#define AGE_DETECT_H

#include <memory>
#include <opencv2/opencv.hpp>

class AgeDetect {
    class AgeDetectImpl;
    std::unique_ptr<AgeDetectImpl> m_ageDetectImplPtr = nullptr;
public:
    AgeDetect(std::string token);
    ~AgeDetect();

    std::string getAge(std::string imagepath);
    std::string getAge(uint8_t* buffer, size_t rows, size_t cols);
    std::string getAge(const cv::Mat& image);
};


#endif

AgeDetect.cpp

#include "ageDetect.h"
#include "ageDetectImpl.h"

AgeDetect::~AgeDetect() = default;

AgeDetect::AgeDetect(std::string token) {
    //m_ageDetectImplPtr = std::make_unique<AgeDetectImpl>(token);
    }

Error Message

 error: invalid application of ‘sizeof’ to incomplete type ‘AgeDetect::AgeDetectImpl’
  static_assert(sizeof(_Tp)>0,

Edit Fixed header guards

cyrusbehr
  • 1,100
  • 1
  • 12
  • 32
  • You need a pimpl deleter: https://stackoverflow.com/questions/9954518 – Eljay Jun 26 '19 at 21:59
  • 1
    Also, your header guard `__AGE_DETECT_H__` is a reserved identifier because it has two underscores in it, also because it starts with an underscore at the global (preprocessor) scope. – Eljay Jun 26 '19 at 22:01
  • @Eljay can you elaborate more on what a pimpl deleter is? From that thread, it looks like my wrapper class needs to have a deleted, which mine does `~AgeDetect();` – cyrusbehr Jun 26 '19 at 22:05
  • @Eljay and thank you for the info about the header guard, I fixed that – cyrusbehr Jun 26 '19 at 22:07
  • Can it be the assignment to nullptr at the beginning? No easy access to a compiler at the moment – CuriouslyRecurringThoughts Jun 26 '19 at 22:09
  • Can you guys explain why initializing it to `nullptr` is an issue? – cyrusbehr Jun 26 '19 at 22:17
  • Look at the answer that duplicates this post https://stackoverflow.com/questions/25850629/unique-ptr-pimpl-forward-declaration-and-complete-definition In particular the section "Why is the complete type required?" – CuriouslyRecurringThoughts Jun 26 '19 at 22:40

1 Answers1

0

As mentioned by CuriouslyRecurringThoughts and Jarod42, the issue was due to the assignment of nullptr to m_ageDetectImplPtr

The following code works

    class AgeDetectImpl;
    class AgeDetect {
    public:
        AgeDetect(std::string token);
        ~AgeDetect();

        std::string getAge(std::string imagepath);
        std::string getAge(uint8_t* buffer, size_t rows, size_t cols);
        std::string getAge(const cv::Mat& image);

    private:
        std::unique_ptr<AgeDetectImpl> m_ageDetectImplPtr;
    };
cyrusbehr
  • 1,100
  • 1
  • 12
  • 32