简体   繁体   English

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

[英]Declaring struct members that are initialised later (C++)

I need to have a variable that is declared in a struct to be initialised with a value later.我需要在结构中声明一个变量,以便稍后使用值进行初始化。 It's basically because its initialisation depends on another member of the structure, which only has a value after some functions have been done.这基本上是因为它的初始化依赖于结构的另一个成员,只有在完成某些功能后才有值。

This sounds a bit weird, so I'll show my code:这听起来有点奇怪,所以我将展示我的代码:

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);
     ...
}

Currently this code throws this error: error: no match for call to '(std::vector<cv::Moments>) (std::vector<std::vector<cv::Point_<int> > >::size_type)'目前此代码抛出此错误: error: no match for call to '(std::vector<cv::Moments>) (std::vector<std::vector<cv::Point_<int> > >::size_type)'

How should I initialise the moments vector array so that it has enough space for all the contours?我应该如何初始化矩向量数组,以便它有足够的空间容纳所有轮廓?

There's nothing wrong or weird about what you're trying to do.您尝试做的事情没有错或奇怪。 This is an example of an initializer function (or what would be called a constructor for a class).这是一个初始化函数的例子(或者被称为类的构造函数)。

What isn't entirely clear is whether struct1 is meant to be the struct you are initializing or if it is an input that you are using to return a new struct (since your function does define its return type as my_struct as well).不完全清楚的是struct1是您正在初始化的结构,还是您用来返回新结构的输入(因为您的函数确实将其返回类型也定义为my_struct )。 In either case, it is generally recommended to pass your structs by reference rather than by value or as return values.在任何一种情况下,通常建议通过引用而不是通过值或作为返回值传递结构。

You could try something like this:你可以尝试这样的事情:

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

Of course, if you really are using C++, you should question why you are using a struct to represent what seems to be a string?当然,如果您真的在使用 C++,您应该质疑为什么要使用结构来表示似乎是字符串的内容?

Once you've allocated memory this way, it is important that you free the memory as well in order to avoid memory leaks.以这种方式分配内存后,释放内存以避免内存泄漏也很重要。 A single object can be deallocated using delete , but an array should be deallocated using delete [] , for example:可以使用delete释放单个对象,但应使用delete []释放数组,例如:

delete [] some_struct.my_array;

Additionally, it is considered good practice to set pointers to null after deallocating them to avoid referencing stale memory segments.此外,在释放指针后将指针设置为 null 被认为是一种很好的做法,以避免引用过时的内存段。 This can be done like this:这可以像这样完成:

some_struct.my_array = nullptr;

Finally, this all gets a bit tedious to manage, particularly if the lifetime and ownership of the object is more complex.最后,这一切管理起来有点乏味,特别是如果对象的生命周期和所有权更复杂的话。 To deal with this, the standard library has unique_ptr and shared_ptr objects that will automatically deallocate an object when it is no longer being used.为了解决这个问题,标准库有unique_ptrshared_ptr对象,它们将在不再使用时自动释放对象。

I don't think it makes sense to go into detail about the differences and uses of each since there are innumerable resources here and elsewhere on the topic.我认为详细介绍每种方法的差异和用途没有意义,因为这里和其他地方有无数关于该主题的资源。

You have to use malloc()你必须使用 malloc()

char* struct1.my_array = new char[struct1.size];

Edited: Actually you can use malloc or new.编辑:实际上您可以使用 malloc 或 new。 In this case - doesn't matter.在这种情况下 - 没关系。 If you prefer malloc you have to free memory with free(), otherwise you have to use new/delete.如果您更喜欢 malloc,则必须使用 free() 释放内存,否则必须使用 new/delete。 Usually new/delete is good to be used while creating objects, when you are dealing with structs and primitive type stick to malloc.通常在创建对象时使用 new/delete 是很好的,当你处理结构和原始类型时,坚持使用 malloc。

New/Delete operator are usually invokes constructors/destructors and they are a little bit slower than malloc/free. New/Delete 运算符通常调用构造函数/析构函数,它们比 malloc/free 慢一点。 So why you have to pay (even a little) performance cost for nothing?那么为什么您必须白白付出(甚至一点点)性能成本呢?

Seems to me this is very simple question在我看来这是一个非常简单的问题

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM