I think it is better to detect instances of your object using
QueryInterface rather than trust the cid. You can simply declare
an iid locally in your implmentation and have the QI method
respond with a pointer to your base object when QI'd for that
iid. I think this is safer and has no more overhead than what you
propose.
John.
Tobias Oberstein wrote:
> if I know the CID of the component sitting behind an interface XX
> (via nsIClassInfo) and I know the implementing C++ class
> associated with the CID, is it then safe to "downcast" XX to
> the implementing class?
>
> btIBuffer* other;
> btCBuffer* otherBuf = static_cast<btCBuffer*>(other);
>
> Tobias.
>
>
> I only want to do this in very _rare_ controlled cases - here, I want
> to do some deep swapping of data held by components:
>
>
> /* void swap (in btIBuffer other); */
> NS_IMETHODIMP
> btCBuffer::Swap(btIBuffer *other)
> {
> // implements deep swapping
>
> PR_ASSERT(other);
> nsresult rv;
>
> nsCOMPtr<btIBuffer> otherBuffer(other);
> nsCOMPtr<nsIClassInfo> clsInfo (do_QueryInterface(otherBuffer, &rv));
>
> if (NS_FAILED(rv)) { // need nsIClassInfo to get to the ClassID
> return NS_ERROR_FAILURE;
> }
>
> // get the other components ClassID
> nsCID* clsId = nsnull;
> rv = clsInfo->GetClassID (&clsId);
>
> if (NS_FAILED(rv)) {
> return NS_ERROR_UNEXPECTED;
> }
>
> // get this components ClassID
> nsCID thisClsId = this->GetCID ();
>
> // bail out if those CIDs do not match !
> if (thisClsId.Equals(*clsId) == PR_FALSE) {
> return NS_ERROR_FAILURE;
> }
>
> // now, it should be safe to downcast the interface
> // to the component ..
> btCBuffer* otherBuf = static_cast<btCBuffer*>(other);
>
> // .. and do all the swap stuff directly
> void* data = otherBuf->data_;
> PRUint32 size = otherBuf->size_;
> PRUint32 length = otherBuf->length_;
> PRUint32 lbmask = otherBuf->lbmask_;
>
> otherBuf->data_ = this->data_;
> otherBuf->size_ = this->size_;
> otherBuf->length_ = this->length_;
> otherBuf->lbmask_ = this->lbmask_;
>
> this->data_ = data;
> this->size_ = size;
> this->length_ = length;
> this->lbmask_ = lbmask;
>
> return NS_OK;
> }
>