use shared_ptr for better readibility