I'm having issues designing from a C# perspective.
I've got a class that returns a raw pointer to a class. Using a contrived example:
class Subject
{
  private:
   Topic _topic;
  public:
    void  AddTopic(Topic* topic)
    {
      delete _topic;
      _topic = topic;
    }
    void Update()
     {}
  ~Topic(){
       delete _topic;
   }
}
class Student
{
  vector<Topic*> _topicsCache;
  
  private:
    void DoSomething()
    {
      for(const auto & x: _topics)
      {
          x->Update(); //code segfaults
      }
    }
}
In the original code at some point somewhere, the Subject class gets deleted.
I'm thinking of refactoring the code without being too invasive to use a shared_ptr instead. Unfortunately, shared_ptr doesn't provide a callback to let me know when I can delete from the topics cache.
I was also thinking of a TopicsCache class to track all the Topics manually. The Topic would take a reference to the cache and remove itself when its destructor it's called. So:
class Topic
{
public:
  Topic(TopicsCache &topicCache);
  ~Topic()
  {
     topicCache.Remove(this);
  }
}
class TopicsCache
{
    void Remove(Topic* topic)
    {
        subjects->Remove(topic);
    }
} 
Is this frowned upon in C++ land?