My question is, how does one have a client use a class without calling "new".
You just don't use new; you put the object on the stack instead:
But that's not actually your problem. Your problem is that your MyClass API is not designed well; it makes certain assumptions about the lifetime of the instances passed to its interface that are trivially easy to break, as you noted. addEnt() assumes that the entity given to it will outlive the MyClass instance invoking addEnt.
You could just live with this limitation, hopefully by documenting it very clearly. This is less than ideal because it's still easy to misuse your API, and good APIs should strive to be difficult to misuse. Instead, consider re-evaluating your design.
MyClass could reject ownership of the Entity objects; this means it would assume the responsibility for cleaning them up is handled outside MyClass (and you remove the code in the destructor that deletes the pointers in the entity list). This helps a little, but does still leave you in a situation where the entity can outlive the MyClass and thus create a crash bug when you eventually dereference the now-bogus pointer.
Instead, MyClass should create the entity itself, and retain the ownership of it. It can return a reference to the newly-added entity for client code to use; client code should know that it does not assume ownership of the entity because the MyClass instead has it. In that work, addEnt would look like this:
Entity* MyClass::addEnt() {
Entity * result = new Entity();
ents.push_back(result);
return result;
}
If you need to be able to pass parameters to the entity constructor, you can either reflect those parameters through into addEnt() so they are passed there, or you could make addEnt copy the entity given to it:
Entity* MyClass::addEnt(const Entity & prototype) {
Entity * result = new Entity(prototype);
ents.push_back(result);
return result;
}
In C++, you could also use forwarding and template parameter packs to invoke the desired constructor of Entity through the addEnt call, and you should also consider using unique_ptr<T> instead of bare pointers within your class. Alternatively, if you want to share ownership of the entity between MyClass and the client code, you can use shared_ptr<T> for the entities.