Shared_ptr имеет значение null при повторной итерации в std::Vector

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

map<string,map<string,vector<StructAbsTypeObject>>>

Здесь я создаю общие объекты и назначаю их, которые действительны во время первой проверки, но при второй проверке shared_ptr возвращает null. Мне нужно знать причину. Код кажется хорошим, но не знаю, где он идет не так.

//Code begins
#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <memory>

using namespace std;

class Test {
public:
  Test(int i):t(i) {
  }

private:
  int t;
};

class ConcTypeObject {
public:
  ConcTypeObject() {
  }

  ConcTypeObject(const ConcTypeObject& other) {
    m_ptr_Test = other.m_ptr_Test;
  }

  ConcTypeObject& operator=(const ConcTypeObject& other) {
    m_ptr_Test = other.m_ptr_Test;
  }

  void setTest(shared_ptr<Test> ptr) {
    cout << "setTest" << endl;
    m_ptr_Test = ptr;
  }

  shared_ptr<Test> getTest() {
    return m_ptr_Test;
  }

  bool isValid() {
    if (m_ptr_Test) {
      return true;
    } else {
      return false;
    }
  }

private:
  shared_ptr<Test> m_ptr_Test;
};


class AbsTypeObject {
public:
  explicit AbsTypeObject(const string str) {
    m_str = str;
  }

  AbsTypeObject(const AbsTypeObject& other) {
    m_str = other.m_str;
    m_ptr_ConcTypeObject = other.m_ptr_ConcTypeObject;
  }

  AbsTypeObject& operator=(const AbsTypeObject& other) {
    m_str = other.m_str;
    m_ptr_ConcTypeObject = other.m_ptr_ConcTypeObject;
  }

  bool operator==(const AbsTypeObject& other) {
    if (m_str == other.m_str)
      return true;
    else 
      return false;  
  }

  void setConcTypeObject(shared_ptr<ConcTypeObject> ptr) {
    m_ptr_ConcTypeObject = ptr;
  }

  shared_ptr<ConcTypeObject> getConcTypeObject() {
    return m_ptr_ConcTypeObject;
  }

  bool isValid() {
    if (m_ptr_ConcTypeObject) {
      cout << "AbsTypeObject 1 " << endl;
      return m_ptr_ConcTypeObject->isValid();
    } else {
      cout << "AbsTypeObject 2 " << endl;
      return false;
    }
  }

private:
  string m_str;
  shared_ptr<ConcTypeObject> m_ptr_ConcTypeObject;
};


class StructAbsTypeObject {
  public:
    StructAbsTypeObject(const string str):m_AbsTypeObject(str) {
    }

    void SetAbsTypeObject(AbsTypeObject& id) {
      m_AbsTypeObject = id;
    }

    AbsTypeObject& GetAbsTypeObject() {
      return m_AbsTypeObject;
    }

    private:
    AbsTypeObject m_AbsTypeObject;
};


class Executor {
public:
    static Executor m_Executor;
    static Executor& get() {
        return m_Executor;
    }

    Executor() {
      StructAbsTypeObject sid(std::string("ABCD"));
      vector<StructAbsTypeObject> a_vecstid;
      a_vecstid.push_back(sid);
      m_executormap["ExecutorInterface"]["ExecutorName"] = a_vecstid;
    }

    void check() {
      for(auto outermap : m_executormap) {
        for(auto innermap : outermap.second) {
          for(auto vec_element: innermap.second) {
            if (vec_element.GetAbsTypeObject().isValid()) {
              cout << "PTR VALID" << endl;
            } else {
              cout << "PTR NOT Valid" << endl;
            }
          }
        }
      }
    }

    void fillAbsTypeObject(AbsTypeObject &id) {
      shared_ptr<Test> ptr_test = make_shared<Test>(20);
      shared_ptr<ConcTypeObject> ptr_ConcTypeObject = make_shared<ConcTypeObject>();
      id.setConcTypeObject(ptr_ConcTypeObject);
      id.getConcTypeObject()->setTest(ptr_test);
    }

    void Init(AbsTypeObject id) {
      for(auto outermap : m_executormap) {
        for(auto innermap : outermap.second) {
          for(auto vec_element: innermap.second) {
            if (vec_element.GetAbsTypeObject() == id) {
              cout << "Id Equal" << endl;
              fillAbsTypeObject(id);
              vec_element.SetAbsTypeObject(id);
              if (vec_element.GetAbsTypeObject().isValid()) {
                cout << "PTR VALID" << endl;
              } else {
                cout << "PTR NOT Valid" << endl;
              }
            }
          }
        }
      check();
      }
    }

private:
  using executormap = map<string,map<string,vector<StructAbsTypeObject>>>;
  executormap m_executormap;
};

Executor Executor::m_Executor;

int main() 
{
  AbsTypeObject id(std::string("ABCD"));
  Executor::get().Init(id);

}
//Code Ends

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

//Output Begins

Id Equal
setTest
AbsTypeObject 1 
PTR VALID
AbsTypeObject 2 
PTR NOT Valid

//Output Ends

PTR NOT VALID выводится при выполнении функции проверки. Ожидаемый результат PTR ДЕЙСТВИТЕЛЬНО в обоих случаях.

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

Заранее спасибо.

Создать минимальный воспроизводимый пример

eerorika 12.03.2019 11:25

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

idmean 12.03.2019 11:40

Есть ли какая-то особая причина, по которой вы вручную определяете конструктор копирования/операторы присваивания? Компилятор сделает это за вас правильно (см. также правило пяти). Кроме того, включите предупреждения в вашем компиляторе, AbsTypeObject& operator=(const AbsTypeObject& other) утверждает, что возвращает значение, но не делает этого. Это неопределенное поведение. (Я упоминал, что вы должны позволить компилятору сгенерировать эту функцию, потому что он сделает это правильно?)

Max Langhof 12.03.2019 11:45
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
3
289
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В ваших циклах for:

  for(auto outermap : m_executormap) {
    for(auto innermap : outermap.second) {
      for(auto vec_element: innermap.second) {

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

Просто измените их на ссылки, чтобы обновить исходные списки:

  for(auto& outermap : m_executormap) {
    for(auto& innermap : outermap.second) {
      for(auto& vec_element: innermap.second) {

Спасибо за Ваш ответ. Не имел, хотя об этом. Теперь это работает.

TechTotie 12.03.2019 11:59

Другие вопросы по теме