Shared_ptr равен нулю при повторении в std :: Vector - PullRequest
0 голосов
/ 12 марта 2019

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

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

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

//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 VALID в обоих случаях.

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

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

1 Ответ

6 голосов
/ 12 марта 2019

В ваших циклах 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) {
...