// inserted by ideone.com, for the main() function
#include <iostream>
using namespace std;


// ---- ShowRunner.hpp ----

#pragma once
#include <memory> //smart ptr


struct LotsOfData // well this doesn't need to be in this header, but let's keep it brief
{ uint32_t a; int16_t b; int16_t c;
};

class ShowRunner
{
public:
  ShowRunner();
  ~ShowRunner() {} // Lazy

  const LotsOfData& YouMayNotPokeAroundThis();

  void DoStuff();

private:
  std::unique_ptr< LotsOfData > m_allThatData;

  // mounting the damn C++ boiler plate, isn't it just a joy
  ShowRunner(const ShowRunner&) = delete;
  void operator = (const ShowRunner&) = delete;
};


// ---- ShowRunner.cpp ----
ShowRunner::ShowRunner()
: m_allThatData( std::make_unique<LotsOfData>() )
{
	// initialize some ??
}

const LotsOfData& ShowRunner::YouMayNotPokeAroundThis()
{
  return *m_allThatData; // operator overload overload! (is what I sometimes get with the C++ std lib)
}

void ShowRunner::DoStuff()
{
	m_allThatData->a = 123; // See Mom? I can write!
}

int main()
{
    ShowRunner runner;
    
    // we are an observer of the lovely data, so we fetch a nice const ref
    const auto & data = runner.YouMayNotPokeAroundThis();
    
    cout << "a is: " << data.a << endl; // I can read!
    cout << "writing excercise..." << endl;
    runner.DoStuff();
    cout << "a is now: " << data.a << endl;

	//data.b = 567; // Mom forbade it! Does not compute!

    // this warrants a whooping
    auto& nasty = (LotsOfData&)( data );
    nasty.c = 789;
    cout << "c is now: " << data.c << endl;

	return 0;
}
