Передача глобальной строковой переменной между. cpp файлами? - PullRequest
0 голосов
/ 14 января 2020

Я создал заголовочный файл globals.h, в котором есть внешняя строка, которая объявлена ​​как «новое_имя». В image_output. cpp (main) я объявил строку (new_name) как глобальную переменную в верхней части моей функции. Затем я передал эту переменную в erode_image. cpp (файл функции) и обновил ее. Я включил globals.h с основными и функциональными файлами. Проблема в том, что переменная "new_name" не обновляется в файле функции (erode_image. cpp). Кто-нибудь знает, где я делаю ошибку?

globals.h:

#include <iostream>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace cv;
using namespace std;

extern string new_name;

erode_image. cpp (функция):

#include <iostream>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "functions.h"
#include "globals.h"

using namespace cv;
using namespace std;


Mat erode_image(Mat image, int erosion_size, string new_name) {

    new_name += "_eroded";
    Mat element = getStructuringElement(MORPH_RECT, Size(erosion_size, erosion_size));
    erode(image, image, element);

    return image;

}

image_output. cpp (основной):

#include <iostream>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "functions.h"
#include "globals.h"

using namespace cv;
using namespace std;

Mat imgCrop;
string new_name;

int erosion_size = 25;
int dilate_size = 50;
int brightness = 50;
int threshold_to_zero = 3;
int sectionCount = 5;

int main()
{

    String folderpath = "*.png";
    vector<String> filenames;
    cv::glob(folderpath, filenames);

    //removes ./ from beginning of filepath
    for (int i = 0; i < size(filenames); i++) {
        filenames[i] = filenames[i].erase(0, 2);
    }

    for (int i = 0; i < size(filenames); i++) {
        if (filenames[i].find("_cropped") == string::npos) {


            string image_path = filenames[i];
            string new_name = image_path.substr(0, image_path.find_last_of('.')) + "_cropped";
            string extension = image_path.substr(image_path.find_last_of("."));
            Mat img = imread(image_path);
            cvtColor(img, img, cv::COLOR_BGR2GRAY);

            img = crop_image(img);
            img = rotate_image(img);
            img = erode_image(img, erosion_size, new_name);
            //img = average_section_threshold(img, sectionCount, new_name);
            //img = dilate_image(img, dilate_size, new_name);

            string new_file_name = new_name + extension;
            imwrite(new_file_name, img);
            cout << "Image Succesfully Saved!";


            }
    }
}

1 Ответ

0 голосов
/ 14 января 2020

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

Ваш оригинальный код был таким:

globals.h

extern std::string new_name;

other_file. cpp

#include "globals.h"

void func(std::string new_name)  // <- shadows the global new_name
{
    new_name += "_stuff";
}

main. cpp

#include "globals.h"
std::string new_name;

int main()
{
    new_name = "bla";
    func(new_name);

    std::cout << new_name << std::endl;
    return 0;
}

Здесь new_name в main не обновляется, и вывод bla. Это происходит потому, что аргумент в func скрывает глобальную переменную / extern.

Правильный способ использования extern (если вы действительно хотите сохранить глобальный), это удалить аргумент func:

globals.h

extern std::string new_name;

other_file. cpp

#include "globals.h"

void func()
{
    new_name += "_stuff";
}

main. cpp

#include "globals.h"
std::string new_name;

int main()
{
    new_name = "bla";
    func();

    std::cout << new_name << std::endl;
    return 0;
}

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

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

other_file. cpp

void func(std::string& new_name)
{
    new_name += "_stuff";
}

main. cpp

int main()
{
    std::string new_name = "bla";
    func(new_name);

    std::cout << new_name << std::endl;
    return 0;
}

Теперь глобал исчез (как и файл globals.h), и вывод по-прежнему bla_stuff, как и предполагалось.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...