If you're working with COM and Automation in C/C++ (or old versions of Delphi), you should use VARIANTs for the parameters that you want to make optional. Also, optional arguments as defined in C++ style are not supported for COM.
That said, for those VARIANTs that you are to provide when you are calling another object and you want to specify optional parameters (say, when talking to MS Word or Excel via Automation), you will need to initialize those VARIANTS with type VT_ERROR and the scode field set to DISP_E_PARAMNOTFOUND.
When receiving calls from other objects that are capable of omitting parameters (VBScript, JScript), you need to check all your VARIANTs for cases where the type has been set to VT_ERROR and the scode field is DISP_E_PARAMNOTFOUND.
The .NET equivalent is to use an object set to Type.Missing for those parameters mapped to COM optional parameters. The following link may be useful in seeing both sides of the story.
.NET4Office : Type.Missing, C#, and Word (MSDN Blog)
All of this is rooted in how older versions of VB (6 and previous) handled optional arguments. Here is a MS Support KB link that is pretty succinct.
How to pass optional parameters when you call a function from C++ (kb238981)
To address your other questions, it is incorrect to assume that a majority of COM objects are written in C++, as COM is strictly about declaring interfaces and layouts of interfaces in a well known manner. It doesn't matter what language or tools are used to make COM objects so long as they observe and obey the layouts for the interfaces that are supported.
Finally, you're correct about COM being a methodology- not quite in the sense of setting architecture for any specific app, but in making it possible to strongly define interconnected components that may make up an application or may be made available to other applications.