If we keep the friendship, lets at least mitigate by having the BulkXXXOperation classes invoke a private method, rather than mess with private member variables.

How about a BulkOperationBuilder::enqueue(WriteOperation*) method?