I'd write your example this way:
class Session
{
public:
Session(string url, string user, string password);
};
class Camera
{
public:
Camera(Session);
image take_snapshot();
bool reboot();
};
The main idea here is to separate authentication and session/endpoint definition (and perhaps connection) from the camera controls. The class Camera now more closely models a real camera: it has something like a power button and a shutter button. The virtualization of the camera is elsewhere, on its own. This also makes it more obvious what to do if someone wants to make a USB session for a different camera, etc.
A secondary idea here is that objects are created with valid state from the beginning. There is here no way to configure a Camera without a password for example, so calling take_snapshot() without credentials is simply not possible. Of course the credentials may be invalid, but that can be checked by some method which might be called in one of the constructors.
As an aside, there is nothing wrong with free functions. OOP is overrated, we all know it, and you shouldn't feel any need to apologize if free functions work in your use case. Dumb structs can be better than pointless getter and setters--especially if you're not building a reusable library that has ABI compatibility requirements.