The problem is not due to protected/public issues. It looks like a scope/pointer issue.
Your problem is here:
creates an unnamed temporary object. I'll call this object "foo".
Terrain is then set to point to "foo".
However, because "foo" is temporary, it goes out of scope immediately (either just before the Draw() call, or after the startProcess function ends -- I forget exactly when temporary objects die).
So as soon as foo goes out of scope and dies... "Terrain" becomes a bad pointer, since the object it points to no longer exists. At that point, anything you try to do with it (like draw) will have undefined behavior (hence the weirdness you're seeing).
You need to give the object a more permanent scope. A temporary object will not do. There are several ways you can accomplish this:
1) Change Terrain to be an object instead of a pointer.
2) Allocate the object with new (
Terrain = new CTerrain(GetSafeHwnd());
). This will require you to
when done to prevent memory leaks.
3) Use technique #2, but wrap it in a smart pointer so you don't have to worry about cleanup. std::shared_ptr will work nicely.