Turning a data class with too much functionality into a POD - SysLat Cleanup #2 This is a follow up question to Tuning the data class for the SysLat System Latency Testing hardware for gaming computers - SysLat Cleanup #1.
Since the program is too large and complex to put into one question I have also posted a question about the USB controller and the dialog that controls the entire program.
Here's my open source project: https://github.com/Skewjo/SysLat_Software
Today I'm attempting to clean up my &quot;SysLatData&quot; class, and the effort has gone very well so far, and I'm looking to pretty well finalize it now if possible.
Header file here: https://github.com/Skewjo/SysLat_Software/blob/master/SysLatData.h
Implementation here: https://github.com/Skewjo/SysLat_Software/blob/master/SysLatData.cpp
Definition and use here: https://github.com/Skewjo/SysLat_Software/blob/master/SysLat_SoftwareDlg.cpp
#pragma once

//Without the following 2 macros the date library spits out 50+ errors about min and max being undefined.
#undef max 
#undef min
#include &lt;date/date.h&gt; //Should likely move this to StdAfx.h, but I'm not sure if I can because of the macro issue.
using namespace date;
using namespace std::chrono;

constexpr size_t MOVING_AVERAGE = 100;
constexpr size_t EVR_MIN = 3;
constexpr size_t EVR_MAX = 100;

struct SYSLAT_DATA {
    struct Statistics {
        std::size_t counter = 0;
        int total = 0;
        double average = 0.0;
        int median = 0;
        int max = 0;
        int min = 0;
        double approxMovingAvg = 0.0;
    };

    vector&lt;int&gt;         m_allResults;
    vector&lt;string&gt;      m_v_strRTSSWindow;
    vector&lt;string&gt;      m_v_strActiveWindow;
    
    Statistics          m_statistics;
    Statistics          m_statisticsEVR;
};

class CSysLatData
{
protected: 
    SYSLAT_DATA         m_sld;
    Json::Value         m_JSONsld; //this is basically a second copy of the data... will probably eat up a BOATLOAD of memory for no reason. There's got to be a better way...
    int                 systemLatency = 0;

    std::mutex          m_Mutex;
    string              m_strError = &quot;&quot;;

    const system_clock::time_point  m_startTime = system_clock::now();
    system_clock::time_point        m_endTime;
    duration&lt;int&gt;                   m_testDuration; 

public:
    const SYSLAT_DATA&amp;  GetData() {return m_sld;}
    const Json::Value&amp;  GetJSONData() { return m_JSONsld; }
    const int&amp;          GetSystemLatency() { return systemLatency; }

    double              CalculateMovingAverage(double currentAvg, int input);
    void                SetEndTime();
    void                UpdateSLD(unsigned int loopCounter, const string&amp; sysLatResults, string RTSSWindow, string activeWindow, DWORD fgPID, DWORD rtssPID);
    void                AppendError(const string&amp; error);
    
    void                CreateJSONSLD(); // I think I may need to make this and the following functions return bools or ints based on whether or not they failed.
    void                ExportData(int testNumber, string path = &quot;.\\SysLat_Logs&quot;, int totalLogs = 10000);

    string              m_RTSSVersion = &quot;0.0.0&quot;;
    string              m_targetApp = &quot;Unknown&quot;;
    string              m_boxAnchor = &quot;Unknown&quot;;

    bool                m_bDataExported = false;
    bool                m_bDataUploaded = false;
};
Suggestions:

Make export data a static method, pass in the object to be exported.
Do not have a member variable just to store JSON data; generate the JSON only as part of the export method.