Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 声明稍后初始化的结构成员(C+;+;)_C++_Opencv_Struct_Initialization_Declaration - Fatal编程技术网

C++ 声明稍后初始化的结构成员(C+;+;)

C++ 声明稍后初始化的结构成员(C+;+;),c++,opencv,struct,initialization,declaration,C++,Opencv,Struct,Initialization,Declaration,我需要有一个在结构中声明的变量,以便稍后用值初始化。这基本上是因为它的初始化依赖于结构的另一个成员,它只有在完成某些功能后才有一个值 这听起来有点奇怪,所以我将显示我的代码: struct frame { Mat thresholded; vector<vector<Point> > contrs; vector<Moments> momts; }; frame obj_detect(frame img) { // Get c

我需要有一个在结构中声明的变量,以便稍后用值初始化。这基本上是因为它的初始化依赖于结构的另一个成员,它只有在完成某些功能后才有一个值

这听起来有点奇怪,所以我将显示我的代码:

struct frame
{
    Mat thresholded;
    vector<vector<Point> > contrs;
    vector<Moments> momts;
};

frame obj_detect(frame img)
{
    // Get contours from image
    findContours(img.thresholded, img.contrs, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
    // Initialise moments vector big enough for all contours' moments
    img.moments(img.contrs.size());
    ...
    return img;
}

int main()
{
     frame frame1;
     frame1 = obj_detect(frame1);
     ...
}
结构框架 { 垫阈值; 矢量控制; 向量momts; }; 帧对象检测(帧img) { //从图像中获取轮廓 findContours(图像阈值、图像控制、CV\u RETR\u外部、CV\u链近似\u简单); //初始化足够大的力矩向量,以适应所有轮廓的力矩 惯性矩(惯性控制尺寸()); ... 返回img; } int main() { 框架1; frame1=对象检测(frame1); ... } 当前此代码引发以下错误:
错误:调用“(std::vector)(std::vector::size_type)”不匹配

我应该如何初始化矩向量数组,以便它有足够的空间容纳所有轮廓?

您必须使用malloc()

编辑: 实际上,您可以使用malloc或new。在这种情况下-没关系。如果喜欢malloc,则必须使用free()释放内存,否则必须使用new/delete。通常,在创建对象时,在处理结构和基本类型时,可以使用new/delete


New/Delete操作符通常调用构造函数/析构函数,它们比malloc/free慢一点。那么,为什么您必须免费支付(甚至是一点点)性能成本呢?

您尝试做的事情没有任何错误或奇怪之处。这是一个初始化器函数(或类的构造函数)的示例


不完全清楚的是,
struct1
是否是您正在初始化的结构,或者它是否是用于返回新结构的输入(因为您的函数也将其返回类型定义为
my_struct
)。在这两种情况下,通常建议通过引用而不是通过值或作为返回值来传递结构

您可以尝试以下方法:

void my_function(const my_struct& input_struct, my_struct& output_struct)
{
  ...
  output_struct.size = ...;
  output_struct.my_array = new char[output_struct.size];
  ...
}
some_struct.my_array = nullptr;

当然,如果你真的在使用C++,你应该问为什么使用Strutt来表示什么是字符串? 以这种方式分配内存后,释放内存以避免内存泄漏也很重要。可以使用

delete
解除分配单个对象,但应使用
delete[]
解除分配数组,例如:

delete [] some_struct.my_array;
此外,在取消分配指针后将其设置为null以避免引用过时的内存段被认为是一种良好的做法。可以这样做:

void my_function(const my_struct& input_struct, my_struct& output_struct)
{
  ...
  output_struct.size = ...;
  output_struct.my_array = new char[output_struct.size];
  ...
}
some_struct.my_array = nullptr;
最后,这一切都变得有点乏味,尤其是当对象的生命周期和所有权更复杂时。为了解决这个问题,标准库有
唯一的\u ptr
共享的\u ptr
对象,当对象不再使用时,这些对象将自动解除分配


我认为详细说明每种方法的区别和用途是没有意义的,因为这里和其他地方都有无数关于这一主题的资源。

在我看来,这是一个非常简单的问题

    my_struct my_function(my_struct struct1)
    {
        ...
        struct1.my_array = malloc(struct1.size); // Initialise the array
        ...
    }

为什么不使用std::string来代替size和C字符串字段呢?它实际上不是字符数组,而是一些奇怪的openCV向量。我只是把它作为字符数组,这样它就更通用了。如果这是错误的事情,我会改变它。@ TooB610:好的,所以使用<代码> STD::向量< /代码>。我认为学习一些基本的C++会更有效率。<代码> char */COD>与代码>矢量< /代码>确实有很大的不同。如果您的实际代码是
向量my_数组
那么
myu函数中的代码应该是
myu数组.resize(struct1.size)。请把你的真实代码改成“编译”的东西。<代码> S/MalCube()/NeX[]/< /Cord> >这是什么地方?问题是加标签C++,所以最好使用C++技术而不是C语言的遗留物,这是C的继承方式。有C++的方法吗?你必须使用Kamen下面发布的新的。“通常建议通过引用而不是通过值或作为返回值来传递结构“事实上,情况正好相反,除非所需的语义是修改现有对象。我不同意。对于大型结构,按值传递结构或将其用作返回值可能代价高昂,除非编译器能够避免复制。这正是
const
关键字的作用所在,也是我将其包含在示例中的原因。如果在函数中需要结构的副本,那么通过值传递比通过
const
reference传递给编译器更多的优化余地。如果您不需要副本,
const
参考非常有意义。如果函数的目的是初始化一个新的struct对象并将其返回给调用者,则按值返回更清晰,更不容易出错,而且编译器通常可以忽略副本,而新对象是“就地”生成的在谷歌的C++风格指南中,C++社区中有点好玩。知道和擅长软件并不意味着了解C++。编写这些指南的人可能是精通C和/或Java的程序员。