zoukankan      html  css  js  c++  java
  • 关于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;
    }
    

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

    或者说这是一个妙用吧。

  • 相关阅读:
    隐藏TabControl的标签 上海
    最近写的一个存储过程 上海
    DBUS 介绍 上海
    存储过程 几个小例子 上海
    C# BHO 上海
    EXEC和sp_executesql的区别 上海
    office文档转换成mht文档(准备、原理篇) 上海
    Dictionary 排序 上海
    .Net 开源资源 上海
    Geant4.9.5.p01 in ubuntu12.04 OpenGL driver.
  • 原文地址:https://www.cnblogs.com/raymon/p/2425477.html
Copyright © 2011-2022 走看看