正在加载...
 
< C++ 实践 ---...
C++ 内置类型(未... >
C++ 实践 ------ 指针上的奇技淫巧 
  主题:[编程] | 标签:C/C++ | 浏览数(253) | 评论数(2) | 10-04 20:22

在这里,我使用一个程序作为本文的开始:

#include <iostream>
#include <conio.h>

class CTest
{
public:
    int Func(int nNum);
private:
    int m_nNum;
};

int CTest::Func(int nNum)
{
    return nNum;
}

int main()
{
    CTest* pTest = NULL;
    CTest* pTest2;
    CTest* pTest3 = new CTest;
    delete pTest3;

    std::cout << pTest->Func(10) << std::endl;

    // 在 VS2003 下,应该注释此行再运行
    std::cout << pTest2->Func(10) << std::endl;
    std::cout << pTest3->Func(10) << std::endl;

    system("PAUSE");
    return 0;
}

 

读者可以在 MSVC6,VS2003,GCC 下测试本程序,除了 VS2003 下,需要注释"std::cout << pTest2->Func(10) << std::endl;"之外,程序都能正常运行。

我们可以得到这样一个结论,如果某成员函数没有访问成员变量,那么无论指针的值如何,对此成员函数的访问通常是有效的。

这种技巧被称之为奇技淫巧并不为过,不过云风有一文《更健壮的 C++ 对象生命期管理》谈及到它的用法(笔者对此持保留态度)。一般来说,我们是不会使用这种技巧的。我们来看看真实项目中的一个缩影:

// Thing
class CThing
{
public:
    void Dosomething();
};


// Thing Manager
class CThingMgr
{
public:
    // Check
    bool Check(int nID);
    // Remove
    void Remove(int nID);
    CThing* GetThing(int nID);
private:
    std::map<int /*ID*/, CThing*> m_mapThing;
};

bool CThingMgr::Check(int nID)
{
    // Do something without variables
    return true;
}

void CThingMgr::Remove(int nID)
{
    std::map<int, CThing*>::iterator it = m_mapThing.begin();
    if (m_mapThing.end() == it)
        return;

    m_mapThing.erase(it);
}

 

使用:

CThing* pThing = mapThing->GetThing(nID);
// 做了很多事情之后
mapThing->Remove(nID);
// 又做了很多事情
pThing->Dosomething(); // 这里 pThing 已经被删除

 

我们可以看到,如果函数 Dosomething 没有访问 CThing 的成员变量,那么运行将很正常。假如某天,某个维护此代码的人员加入了一些访问成员变量的代码,那么程序将崩溃,并且这种错误非常难以发现(特别是维护人员和开发人员不是同一个人时)。

我们可以考虑使用一些技术来解决这个问题,在此笔者经过分析考虑认为使用智能指针来解决是最佳方案。

http://www.i170.com/Article/111668/trackback

评论:

  liangar  10-04 21:42 评论  

我看第一个例子,问题:test2还没有指向一个地方,怎么用?

其他指针变量都有问题,这样的程序没有办法运行才对。

 

另外,不用using,到处都要std::,不是c++风格。

 

c++编写效率高,所以用在关键地方比较多,如果经常有什么指针指到空,那就建议别用c++了。惹的麻烦比办的事多。

  killercat  10-05 20:40 评论  

C++ 的开发效率应该不是很高(c++编写效率高),执行效率倒是不错。

第一个例子的程序,我们不可能故意这么写,只是在偶然的情况下发生了,请看第二个例子。

    发表评论: