use shared ptr