use shared_ptr
refactored by M. -- use shared_ptr & weak_ptr