【问题标题】:Forward declaration cv::Mat前向声明 cv::Mat
【发布时间】:2025-12-29 08:20:08
【问题描述】:

您好,我正在尝试转发声明 cv::Mat 类,但我无法让它工作。它给出消息字段“框架”的类型不完整

OpenGlImpl.h

namespace cv {
    class Mat;
}

class OpenGLImpl {

private:
   cv::Mat frame;

};

我应该如何正确转发声明?

【问题讨论】:

  • 为什么#include 不起作用?
  • #include "opencv2/core/core.hpp"
  • 您不能转发声明成员变量(或基类),因为它会影响您的类的大小。您可以使用不会影响大小的指针等的东西
  • 这个问题*.com/questions/553682/… 明确列出了您可以/不能转发声明的时间和内容
  • ChronoTrigger 和 banuj 我不想将所有这些方法都包含在我的标题中。我想把事情分开,只使用我的 cpp 文件中的方法,我将在其中包含标题。

标签: c++ opencv


【解决方案1】:

您不能在此处使用前向声明。编译器需要有cv::Mat 的定义才能成为OpenGLImpl 的数据成员。

如果你想避免这个限制,你可以让OpneGLImpl 持有一个指向cv::Mat 的(智能)指针:

#include <memory>

namespace cv {
    class Mat;
}

class OpenGLImpl {

private:
   std::unique_ptr<cv::Mat> frame;

};

然后,您可以在实现文件中实例化 unique_ptr 拥有的 cv::Mat

请注意,引用也可以与前向声明一起使用,但您在这里不太可能需要引用语义。

【讨论】:

    【解决方案2】:

    § 3.9.5

    已声明但未定义的类、大小未知或元素类型不完整的数组是未完全定义的对象类型。43 未完全定义的对象类型和 void 类型是不完整类型 (3.9.1 )。 对象不应被定义为不完整的类型。

    struct X; // X is an incomplete type
    X* xp;    // OK, xp is a pointer to an incomplete type. 
    
    struct Y
    {
       X x;   // ill-formed, X is incomplete type
    }     
    
    struct Z
    {
       X* xp;   // OK, xp is a pointer to an incomplete type
    }     
    
    
    void foo() {
    //  xp++; // ill-formed: X is incomplete
    }
    
    struct X { int i; }; // now X is a complete type
    
    X x;           // OK, X is complete type, define an object is fine
    
    void bar() {
      xp = &x;     // OK; type is “pointer to X”
    }
    
    void t()
    {   
      xp++; // OK: X is complete
    }
    

    【讨论】: