Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我应该如何编写正确的COM代码?_C++_Com - Fatal编程技术网

C++ 我应该如何编写正确的COM代码?

C++ 我应该如何编写正确的COM代码?,c++,com,C++,Com,下面的代码正确地发布了所有内容,但看起来很糟糕。我应该如何编写不泄漏引用且可读的COM代码 忽略C++\CLI位 IBaseFilter* leftFilter; if (graph->FindFilterByName(L"Left", &leftFilter) == S_OK) { IPin* leftIn; if (leftFilter->FindPin(L"Audio Input pin (rendered)", &leftIn) == S_OK

下面的代码正确地发布了所有内容,但看起来很糟糕。我应该如何编写不泄漏引用且可读的COM代码

忽略C++\CLI位

IBaseFilter* leftFilter;
if (graph->FindFilterByName(L"Left", &leftFilter) == S_OK)
{
    IPin* leftIn;
    if (leftFilter->FindPin(L"Audio Input pin (rendered)", &leftIn) == S_OK)
    {
        IBaseFilter* meterFilter;
        if (graph->FindFilterByName(L"Meter", &meterFilter) == S_OK)
        {
            IPin* meterIn;
            if (meterFilter->FindPin(L"Input", &meterIn) == S_OK)
            {
                IPin* meterOut;
                if (meterFilter->FindPin(L"Output", &meterOut) == S_OK)
                {
                    try
                    {
                        IntPtr fileName = Marshal::StringToCoTaskMemUni(source->OriginalString);
                        IBaseFilter* sourceFilter;
                        if (graph->AddSourceFilter((LPCWSTR)(void*)fileName, L"Source", &sourceFilter) == S_OK)
                        {
                            IPin* sourceOut;
                            if (sourceFilter->FindPin(L"Output", &sourceOut) == S_OK)
                            {
                                if (graph->Connect(sourceOut, meterIn) == S_OK)
                                {
                                    IBaseFilter* rightFilter;
                                    if (graph->FindFilterByName(L"Right", &rightFilter) == S_OK)
                                    {
                                        IPin* rightIn;
                                        if (rightFilter->FindPin(L"Audio Input pin (rendered)", &rightIn) == S_OK)
                                        {
                                            IBaseFilter* splitFilter;
                                            if (graph->FindFilterByName(L"Split", &splitFilter) == S_OK)
                                            {
                                                IPin* splitIn;
                                                if (splitFilter->FindPin(L"Input", &splitIn) == S_OK)
                                                {
                                                    IPin* splitLeft;
                                                    if (splitFilter->FindPin(L"Left", &splitLeft) == S_OK)
                                                    {
                                                        IPin* splitRight;
                                                        if (splitFilter->FindPin(L"Right", &splitRight) == S_OK)
                                                        {
                                                            if (graph->ConnectDirect(meterOut, splitIn, NULL) == S_OK
                                                                && graph->ConnectDirect(splitLeft, leftIn, NULL) == S_OK
                                                                && graph->ConnectDirect(splitRight, rightIn, NULL) == S_OK)
                                                            {
                                                                this->source = source;
                                                                OnMediaOpened(EventArgs::Empty);
                                                            }
                                                            splitRight->Release();
                                                        }
                                                        splitLeft->Release();
                                                    }
                                                    splitIn->Release();
                                                }
                                                splitFilter->Release();
                                            }
                                            rightIn->Release();
                                        }
                                        rightFilter->Release();
                                    }
                                    else
                                    {
                                        if (graph->ConnectDirect(meterOut, leftIn, NULL) == S_OK)
                                        {
                                            this->source = source;
                                            OnMediaOpened(EventArgs::Empty);
                                        }
                                    }
                                }
                                sourceOut->Release();
                            }
                            sourceFilter->Release();
                        }
                        Marshal::FreeCoTaskMem(fileName);
                    }
                    catch (Exception^) { }
                    meterOut->Release();
                }
                meterIn->Release();
            }
            meterFilter->Release();
        }
        leftIn->Release();
    }
    leftFilter->Release();
}

使用
boost::intrusive_ptr
可以轻松调用
Release
。我想不出其他方法来删除所有嵌套的
if
s,而是让函数抛出异常。考虑用“检查代码< >代码> SyOK < /COD>或其他代码> SUP< <代码> S.< /P> < P> >使用<代码> Boo::BuffsivivpPTR <代码>将获得所有调用“代码>发布< /COD>”的调用。我想不出其他方法来删除所有嵌套的
if
s,而是让函数抛出异常。考虑一下你的函数调用周围的东西,检查代码< > SyOK 或“<代码>投掷< /代码> S.< /P> < P>你可以使用一些智能指针,它将在析构函数中为你调用释放。例如,或Boost的。

您可以使用某种智能指针,在析构函数中为您调用Release。例如,或Boost。

使用智能指针,例如。有一个示例显示了与手动生命周期管理相比,CComPtr如何使事情变得更简单。

使用智能指针,例如。有一个示例显示了与手动生命周期管理相比,CComPtr如何使事情变得更容易。

使用智能指针来放弃所有的
Release()
s,然后使用失败而不是成功作为条件

if (graph->FindFilterByName(L"Left", &leftFilter) != S_OK)
    throw ...;

当然,这可以重构为您最喜欢的内联函数或宏。

使用智能指针放弃所有
版本()
s,然后使用失败而不是成功作为条件

if (graph->FindFilterByName(L"Left", &leftFilter) != S_OK)
    throw ...;

当然,这可以重构为您最喜欢的内联函数或宏。

Woah!!这么多嵌套的
ifs
。如果可能的话,你可以重新考虑逻辑和/或设计。你的意思是
如果(可能)重新考虑设计();)哇!!这么多嵌套的
ifs
。如果可能的话,你可以重新考虑逻辑和/或设计。你的意思是
如果(可能)重新考虑设计();)