外部库的前向声明(PIMPL)也用于方法声明?

问题描述 投票:0回答:1

我已经查看了大量有关前向声明/PIMPL 的帖子,但还没有完全设法让它与我正在使用的外部库一起工作。我想创建一个共享库,客户端不需要包含外部库标头。

这就是我目前拥有的。

################
## myClass.h ##
################

#include <opencv2/opencv.hpp> ------> I want this header in the implementation file instead.

class A;
class B;
class C;

class __declspec(dllexport) myClass
{
public:
    myClass();
    ~myClass();
    cv::Mat myFunction(cv::Mat &img);
private:
    A *_a;
    B *_b;
    C *_c;
};

################
## myClass.cpp ##
################

#include "myClass.h"
#include "a.h"
#include "b.h"
#include "c.h"

myClass::myClass()
{
    _a = new A;
    _b = new B;
    _c = new C;
}

myClass::~myClass()
{
    delete _a;
    delete _b;
    delete _c;
}

cv::Mat myClass::myFunction(cv::Mat &img){ ... }

################
## a.h ##
################

class A
{
public:
    A();
    ... -----> A's methods
};

################
## b.h ##
################

class B{ ... };

################

################
## c.h ##
################

class C{ ... };

################

这是我尝试过的

################
## myClass.h ##
################

namespace cv{
    class Mat; ------> Forward declaration of cv::Mat
}

class A;
class B;
class C;

class __declspec(dllexport) myClass
{
public:
    myClass();
    ~myClass();
    cv::Mat myFunction(cv::Mat &img); ------> Get an error since I'm declaring an incomplete type cv::Mat.
private:
    A *_a;
    B *_b;
    C *_c;
    std::unique_ptr<cv::Mat> _m; ---------> PIMPL for class inside namespace ?
};

################
## myClass.cpp ##
################

#include "myClass.h"
#include "a.h"
#include "b.h"
#include "c.h"
#include <opencv2/opencv.hpp>

myClass::myClass() ------> I'm supposed to do something here ? Inherit _m ?
{
    _a = new A;
    _b = new B;
    _c = new C;
}

myClass::~myClass() -------> Supposed to clear _m (seen = default been used as well) ?
{
    delete _a;
    delete _b;
    delete _c;
}

cv::Mat myClass::myFunction(cv::Mat &img){ ... }

...

如有任何帮助或指导,我们将不胜感激。谢谢

c++ class opencv c++11 forward-declaration
1个回答
0
投票

库的接口部分是一个函数,它接受

cv::Mat
类型的参数并按值返回
cv::Mat
。假设这个简单的代码:

#include <myClass.h>  // your library header
#include <opencv2/opencv.hpp>  // OpenCV header

int main() {
  myClass o;
  cv::Mat input;
  cv::Mat result = o.myFunction(input);
}

我想创建一个共享库,客户端不需要包含外部库标头。

用户如何在不包含定义

cv::Mat
类的 OpenCV 标头的情况下编写此类代码?这根本不可能。

我能想到的唯一可能性是用你自己的库类型完全包装

cv::Mat
并在你的界面中使用它而不是
cv::Mat
。但是,用户将需要使用这种类型而不是众所周知的类型。在我看来,这将是非常糟糕的设计。


顺便说一句,您提到了 PIMPL。但 PIMPL 是另外一回事。这是关于隐藏实现细节。在这里,

cv::Mat
是您的库界面的一部分。你无法隐藏界面,因为那样它就不再是界面了。

© www.soinside.com 2019 - 2024. All rights reserved.