I found the following controller hierarchy useful:
The base controller (called MY_Controller and extends CI_Controller) does not check for login: any controller that extends it is open to the public.
The user_controller extends the base controller and checks that the user is logged_in. Any controller that extends it is only available to logged in users.
The admin_controller extends the user_controller and checks for the admin role. Any controller that extends it is available only to admin users.
All 3 controllers reside inside the core/MY_Controller.php file