Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 16.11.2020, 16:27   #1
maks1331
Форумчанин
 
Аватар для maks1331
 
Регистрация: 20.12.2016
Сообщений: 270
Счастье reference_wrapper и string

Доброго времени суток всем форумчанам, сначала суть, потом вопросы:

При использовании reference_wrapper для реализации полиморфизма и при наличии переменных типа string, при их выводе (в нашем случае метод) - string пустые, а фундаментальные типы в порядке! Но только в том случае, если помещенный в массив элемент выходит из своей области видимости до его вывода(вызова)! Пример:

Используем string и объекты не выходят из области видимости перед вызовом методов.
Код:
#include <iostream>
#include <vector>
#include <functional>
#include <string>

class Parent {
protected:
    int m_value;
    std::string m_firstName = "test";
public:
    Parent(int value) : m_value(value)  {}
    virtual const char* getName() const { return "Parent"; }
    int getValue() const { return m_value; }
    std::string getFirstName() const { return m_firstName; }
};

class Child : public Parent {
public:
    Child(int value) : Parent(value) {}
    virtual const char* getName() const { return "Child"; }
};

int main()
{
    std::vector<std::reference_wrapper<Parent> > v;
    Parent p(7);
    Child ch(8);
    v.push_back(p);
    v.push_back(ch);
    for (int count = 0; count < v.size(); ++count)
        std::cout << "I am a " << v[count].get().getName() << " with value " << v[count].get().getValue() << " " << v[count].get().getFirstName() << "\n";
    return 0;
}
I am a Parent with value 7 test
I am a Child with value 8 test


Используем string и объекты выходят из области видимости перед вызовом методов.
Код:
#include <iostream>
#include <vector>
#include <functional>
#include <string>

class Parent {
protected:
    int m_value;
    std::string m_firstName = "test";
public:
    Parent(int value) : m_value(value)  {}
    virtual const char* getName() const { return "Parent"; }
    int getValue() const { return m_value; }
    std::string getFirstName() const { return m_firstName; }
};

class Child : public Parent {
public:
    Child(int value) : Parent(value) {}
    virtual const char* getName() const { return "Child"; }
};

int main()
{
    std::vector<std::reference_wrapper<Parent> > v;
    {
        Parent p(7);
        Child ch(8);
        v.push_back(p);
        v.push_back(ch);
    }
    for (int count = 0; count < v.size(); ++count)
        std::cout << "I am a " << v[count].get().getName() << " with value " << v[count].get().getValue() << " " << v[count].get().getFirstName() << "\n";
    return 0;
}
I am a Parent with value 7
I am a Child with value 8


И как вы можете наблюдать, происходит магия. Ибо фундаментальный int живой, а string - умер! Если работать с char - проблема отпадает.

win 10 x64, visual studio 19

Вопросы:
1) Почему это происходит? (Кто знает тонкости процессов)
2) Есть типовой способ решения?
3) Использование reference_wrapper на практике вообще актуально? Или лучше реализовывать контейнеры-полиморфы через умный указатель?
формошлеп.рф
witech.su
maks1331 вне форума Ответить с цитированием
Старый 16.11.2020, 17:59   #2
FrosyaZZ
Форумчанин
 
Регистрация: 16.11.2020
Сообщений: 243
По умолчанию

Нет никаких тонкостей.
std::reference_wrapper содержит указатель на то, что передали. При выходе из области видимости вызываются деструкторы, в частности std::string удаляет память (если выделялось) и устанавливает размер в 0. Память после освобождения может некоторое время не меняться. Поэтому базовые типы "там еще лежат", а вместо вашего std::string "лежит" пустой std::string.
FrosyaZZ вне форума Ответить с цитированием
Старый 16.11.2020, 18:03   #3
maks1331
Форумчанин
 
Аватар для maks1331
 
Регистрация: 20.12.2016
Сообщений: 270
По умолчанию

FrosyaZZ, спасибо за объяснение
формошлеп.рф
witech.su
maks1331 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
ошибка в типе данных 'String' and 'System::String' shilovec5377 Общие вопросы C/C++ 2 16.06.2014 16:07
Как преобразовать SIZE_T в string (System String^) calypso Общие вопросы C/C++ 0 09.12.2013 12:43
ошибка [C++ Error] string.h(5): E2344 Earlier declaration of 'String' Pein95 C++ Builder 2 02.04.2013 21:18
Как получить адрес String строки или преобразовать String madboy4ik Общие вопросы по Java, Java SE, Kotlin 6 15.01.2010 11:57