2015-11-06 5 views
-1

Я работаю с библиотекой для выполнения оптимизации по графикам. Поскольку код для этой библиотеки полностью перевернулся, я отказался от попыток адаптировать ее к моим собственным потребностям. Одна из его функций используется для вычисления штрафа за гладкость и принимает только четыре параметра. Однако для правильного вычисления значения штрафа мне понадобится дополнительный параметр (матрица, содержащая множество значений). Первоначально матрица хранится как объект Mat (opencv), а затем загружается, поэтому я не могу просто объявить ее глобальной. Есть ли способ принять эту переменную и сделать ее доступной для всех методов, которые могут ей понадобиться?Использование переменной как глобальной

+1

Пожалуйста, объясните: «Матрица изначально хранится как объект Mat (opencv), а затем загружается, поэтому я не могу просто объявить ее глобальной». – YSC

+0

Данные, которые мне нужны, представляют собой файл yml. Это при загрузке с помощью библиотеки opencv выводит объект Mat. В моем (по общему признанию) опыте работы с C++ я использовал только глобальные переменные, когда они были чем-то простым, например числом или строкой. Поэтому я не знаю, как я могу взять этот объект после его загрузки и сделать его общедоступным. Надеюсь, это немного облегчит ситуацию. – RCountZero

+0

Вы должны опубликовать небольшой пример кода, чтобы показать свою проблему. И да, вы можете определить глобальный и назначить ему позже (это не очень хороший дизайн, хотя). – Miki

ответ

-1

Не зная кода, я понимаю, что вы хотите глобальную переменную, которая предоставляет доступ к методу. Один из способов - объявить Singleton, который содержит указатель на реальный Mat struct.

Когда создается Mat struct, вы передаете его указателю на Singleton. При удалении Mat struct вы указываете Singleton на сброс. Например.

class MatSingleton 
{ 
public: 
    MatSingleton() : pMatInstance(nullptr) {} 
    ~MatSingleton() {} 

    static MatSingleton& GetInstance() 
    { 
     static MatSingleton instance; 
     return instance; 
    } 

    bool IsMatAvailable() 
    { 
     return pMatInstance != nullptr; 
    } 

    void SetMat(Mat *pMat) { pMatInstance = pMat; } 
    Mat* GetMat() const { return pMatInstance; } 

private: 
    Mat  *pMatInstance; 
}; 

[...]  

// Load and fill LoadedMatStruct and inform the Singleton 
MatSingleton::GetInstance().SetMat(&LoadedMatStruct); 


// check if the Mat structure can be accessed 
if (MatSingleton::GetInstance().IsMatAvailable()) 
{ 
    // do smth. with Mat 
    Mat *pMatInstance = MatSingleton::GetInstance().GetMat(); 
} 


// Somewhere else in the code where the Mat structe is destroyed, it is necessary to inform the Singleton 
MatSingleton::GetInstance().SetMat(nullptr); 

Примечание: этот демонстрационный код не является потокобезопасным. Это должно просто проиллюстрировать эту идею.

+1

Для этого вам не нужен синглтон, не говоря уже о указателях на объекты cv :: Mat. Вы должны действительно избегать этого, так как вы, скорее всего, нарушите согласованность консистентных контентов – Miki

+0

@Miki: Спасибо за ваш вопрос. Если cv :: Mat уже является ссылочным подсчитанным объектом, я полностью согласен с тем, что в этом случае нет необходимости в помощнике Singleton. –

0

Хорошо, поэтому я был слишком поспешным и, как ожидалось, «быстрое и грязное» решение получилось ужасно. Как сказал Мики, я могу сначала объявить глобальную переменную, а затем установить значение. Хотя это сработало, это было не то, что выглядело хорошо. Поэтому я потратил некоторое время и увидел, что функция, в которой я нуждалась, может получить структуру с необходимыми данными, позволяющими мне делать то, что мне нужно, без плохого дизайна.

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