use std::shared_ptr