2015-10-17 2 views
-1

Мне нужна переменная, которая объявляется в структуре, которая будет инициализирована со значением позже. Это в основном потому, что его инициализация зависит от другого члена структуры, который имеет значение только после того, как некоторые функции были выполнены.Объявление элементов структуры, которые инициализируются позже (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); 
    ... 
} 

В настоящее время этот код выдает эту ошибку: error: no match for call to ‘(std::vector<cv::Moments>) (std::vector<std::vector<cv::Point_<int> > >::size_type)’

Как следует Инициализируем моменты векторный массив так, что он имеет достаточно места для всех контуров?

+0

Почему бы просто не использовать 'зЬй :: string' вместо размера и строковых полей C? –

+0

На самом деле это не массивы символов, это какая-то странная векторная вещь openCV. Я просто помещал его в виде массивов символов, чтобы он был более общим. Если бы это было неправильно, я изменил бы это. – theoB610

+0

Предположительно, части могут храниться как переменные. После того как вы собрали все собранные части, используйте их для создания рабочего экземпляра вашей структуры. – Peter

ответ

-3

Вы должны использовать таНос()

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

Отредактировано: На самом деле вы можете использовать таНос или новый. В этом случае - не имеет значения. Если вы предпочитаете malloc, вам нужно освободить память с помощью free(), иначе вам придется использовать new/delete. Обычно new/delete хороши для использования при создании объектов, когда вы имеете дело с structs и примитивным типом stick to malloc.

Оператор New/Delete обычно вызывает конструкторы/деструкторы, и они немного медленнее, чем malloc/free. Итак, почему вы должны платить (даже небольшую) стоимость за штуку?

+0

's/malloc()/new [] /'? –

+0

, где это происходит? – theoB610

+2

Вопрос отмечен C++, поэтому лучше использовать методы C++, а не legation от C. – Peter

2

Нет ничего плохого или странного в том, что вы пытаетесь сделать. Это пример функции инициализации (или того, что будет называться конструктором для класса).

Не совсем ясно, является ли 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]; 
    ... 
} 

Конечно, если вы действительно используете C++, вы должны задавать вопросы, почему вы используете-структуру, чтобы представить, что, как представляется, строка?

Как только вы выделили память таким образом, важно также освободить память, чтобы избежать утечек памяти. Один объект может быть высвобождены с помощью delete, а массив должен быть высвобождены с помощью delete [], например:

delete [] some_struct.my_array; 

Кроме того, считается хорошей практикой для установки указателей на нуль после deallocating их, чтобы избежать ссылки устаревших сегментов памяти. Это можно сделать так:

some_struct.my_array = nullptr; 

Наконец, все это становится немного утомительно, чтобы управлять, особенно если срок службы и право собственности на объект является более сложным. Чтобы справиться с этим, стандартная библиотека имеет unique_ptr и shared_ptr объекты, которые автоматически освободят объект, когда он больше не используется.

Я не думаю, что имеет смысл подробно рассказать о различиях и использовании каждого из них, поскольку здесь и в других местах есть бесчисленные ресурсы.

+1

упоминать умные указатели и как освободить их от 'new []' – sp2danny

+0

@ sp2danny Хорошая точка! –

+1

«обычно рекомендуется передавать ваши структуры по ссылке, а не по значению или как возвращаемые значения». На самом деле, это наоборот, если только требуемая семантика не предназначена для изменения существующего объекта. – juanchopanza

-3

Кажется, мне это очень простой вопрос

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

malloc является устаревшим с c, есть ли способ C++ сделать это? – theoB610

+0

Вы должны использовать новый как опубликованный Kamen ниже –

Смежные вопросы