Hopefully someone else will have more in-depth feedback, but let me just say that a design that involves deleting yourself is bad design unless in some very weird, unique circumstance.
I'm talking about this
I'm not sure why you think you need this.
Your code as a whole doesn't make much sense to me. You're doing very weird operations in your del() function that don't make any sense together.
if (control_list[i] = this)
This is assigning this to control_list[i], not testing for equality. Equality is ==.
control_list[i] = 0;
You're trying to assign the list element (a pointer) the value of 0. You should be using the constant NULL or nullptr.
But then you try to erase every element from 0 to i, inside the for loop. You're going to end up erasing out of bounds, causing undefined behavior and possibly crashing your program, because you're going to run out of elements to erase.
So overall, no I don't think your code is right. But I don't know enough about your situation to really suggest a fluent "fix". Perhaps if you showed the actual use cases you want with an example, someone might have a more concrete suggestion.
class session : Controlable
static std::vector <Controlable*> control_list;
If that even compiles, it means you're shadowing your base class's control_list. Not sure if that is what you want.