• 关于c++中类静态成员函数可能破坏类封装性的问题


    问题来自写一个MFC程序中,我们经常在MFC中这样利用多线程:

    BOOL ClassName::OnInitDialog()
    {
    //一些初始化操作
    //开启一个多线程
    CreateThread(NULL,0,ClassName::ThreadProc,(LPVOID)this,0,NULL);
    }
    DWORD WINAPI ClassName::ThreadProc(LPVOID param)
    {
    ClassName *ThisClass = (ClassName*)param;
    ThisClass->m_nThreadNum++;
    
    return 0;
    }

    其中,m_nThreadNum为ClassName类的一个private成员。

    一直以为这样的应用是理所应当的,今天突然发现了它的不恰当:

    m_nThreadNum是类的一个私有变量,为什么可以通过ThisClass->m_nThreadNum访问?这样的形式,在main()函数、或者其他任何与ClassName类无关的地方调用都是不合法的。那么问题可能出现在了ThreadProc这个函数上了。

    众所周知,线程函数的一个重要属性就是静态static。对于类的静态成员函数,当类实例化时,静态成员函数并不会因为实例化数量的变换而变换。不同实例化的对象,共享静态成员函数内存空间。问题貌似就出在这里了:一个对象ObjectA访问该静态成员函数StaticFunc(),StaticFunc并不能根据ObjectA的访问请求,将对对象数据成员的读写操作定位到该对象(ObjectA)内存空间,也就是说,这时的ObjectA对其私有成员的操作,是面向所有对象的私有成员的操作,所以StaticFunc可以完成如下操作:

    StaticFunc()
    {
    ObjectA.privateMember;
    ObjectB.privateMember;
    ......
    }

    对于StaticFunc访问一个对象的私有成员,这个对象都认为是属于自己的StaticFunc函数在访问自己的私有成员,因此可以访问。

    实例代码:

    #include <cstdlib>
    #include <typeinfo>
    #include <iostream>
    
    using namespace std;
    
    class Test
    {
    public:
        Test();
        void AutoFuncA(int);
        static void StaticFuncB(Test*);
    private:
        int m_nNum;
    };
    
    Test::Test()
    {
    
    }
    void Test::AutoFuncA(int num)
    {
        m_nNum = num;
    
        return;
    }
    void Test::StaticFuncB(Test *test)
    {
        cout<<"Test.StaticFuncB.test = "<<typeid(test).name()<<endl;
        //私有成员
        cout<<test->m_nNum<<endl;
    
        return;
    }
    
    int main()
    {
        Test testA,testB;
        testA.AutoFuncA(5);
        testB.AutoFuncA(10);
        cout<<"main.testA = "<<typeid(&testA).name()<<endl;
        cout<<"main.testB = "<<typeid(&testB).name()<<endl;
        testA.StaticFuncB(&testB);
        return 0;
    }
    

    这样就破坏了类的封装性了。

    或者说这是一个妙用吧。

  • 相关阅读:
    开始核心攻坚
    Features postponed for ASP.NET 2.0 Beta 2
    设计模式的认识
    如果您想要提高开发效率,那么给大家推荐一本书,比较实用
    asp.net 2.0 个性化服务探讨
    对于数据缓存依赖的认识
    ASP.NET 2.0学习(1)——XmlDataSource控件中XPath属性之疑惑
    写作的四个境界
    ASP.NET 2.0 product design changes between Beta 1 and Beta 2(a new message from asp.net forum)
    验证控件的问题
  • 原文地址:https://www.cnblogs.com/raymon/p/2425477.html
Copyright © 2020-2023  润新知