VC++6.0&&VS2008&MFC&API学习问题总结(二)(malloc/new/OnReceive)

来源:互联网 发布:hadoop 数据挖掘工具 编辑:程序博客网 时间:2024/05/16 07:21

1、MFC/C++中关于new/delete&malloc/free的使用 :

    以下的两种用法你熟悉么: 

    CSerialPorts* m_pSerial=(CSerialPorts*)lpParameter;   (还不清楚可以查看总结一)

    CThreadDlg* m_Thread=new CThreadDlg(); 左边是定义了指针是空的,右边new也就是在堆中申请的内存。网上也有人是这么解释的:CThreadDlg* m_Thread这个只是给你一把钥匙,并没具体的锁给你;CThreadDlg* m_Thread=new CThreadDlg();而用new的时候就是给你一把锁,然后返回一把钥匙让你能控制这把锁。

    两组内容的关系:

    1)Foo* foo = malloc(sizeof(Foo));//Foo是一个类初始化,那么你将不会调用Foo的构造方法,而只是单纯的分配空间。而且我们只认为你是分配一个空间,而不是想创建一个对象。Foo* foo = new Foo();则会调用Foo的构造方法来初始化对象,也就是说你既要分配空间又要初始化这段空间,让它变成一个对象。对于delete和free也有同样的问题,就是delete会调用析构函数,free则不会。说白了,new\delete玩的是对象,而malloc\free仅仅是内存空间而已。

    2)new/delete通常来说是操作符,就是"+","-"一样,申请内存是自动计算的,可以重载的,而重载之后,就成为了函数。free和delete可以释放NULL指针。

        double* pd = new double;        *pd = 212.211;        delete = pd;        short* ps = new short[128]; // new出一个数组来        ps[2] = 1231;        delete[] ps;  // 请注意delete的语法。
        malloc在申请内存的时候,必须要提供申请的长度,而且返回的指针是void*型,必须要强转成需要的类型。 
        int* pn = (int*)malloc(sizeof(int));              *pn = 15;        free(pn);        pn = NULL; // 置空        free(pn); // OK,没有问题    3)数据的3种存储方式。静态区:  全局变量。   堆: 程序执行是分配的内存 。    栈:函数调用,局部变量。    new出来的内存就是分配到堆上的。程序执行完以后,堆上分配的内存不会被操作系统自动回收,所以你不delete掉的话,操作系统不回收,那块内存就成了没爹没娘的无业有民了,这个就叫内存泄露。我这样说你应该知道为什么书上为什么说new和delete要成对出现了吧。分配出来的内存记得自己回收掉。    静态区和栈上面分配的内存操作系统会自动回收。所以不用delete了。    int * pt ;  pt = new int;这句话的意思是你先声明了一个pt指针,四个字节,放在栈里面的,然后你new了一个int形的数据放在堆里面,再把这个数据的地址赋给pt。delete pt;这个就是把pt指向的地址所占的内存释放掉。其实释放的就是堆上面的那个int。然后你的pt还是存在的,还在栈里面。不过你查它的值时,变成了null。代码解释:    char *p1="name";    int a5=sizeof(p1);//strlen是有多少个字符,sizeof 是计算一个变量的字节数的    a5=strlen(p1);    a5=sizeof(char);    //a5=strlen(char);            //这样的用法是错误的编译都通不过,strlen的参数必须是字符(串)    char *p2=(char*)malloc(sizeof(char)*20);    char *p3=(char *)malloc(_MAX_PATH );    //虽然_MAX_PATH宏定义是260,编译器已经强制了,你自己宏定义是无效的    //为什么不直接指明字节数,而用sizeof(int)这种运算是因为对于不同的计算机,    //对于int的分配空间不一定相同,这样有一定的移值性。 
2、给按键添加图片,按键按下产生图片切换
    m_btnBitmap.LoadBitmaps(IDB_UP, IDB_DOWN, IDB_FOCUSED);  //Disabled状态的图片没有制作      m_btnBitmap.SizeToContent();    //调整按钮大小为图片大小        更为详细的可参考:http://blog.csdn.net/akof1314/article/details/4951836/        更多方法可参考:http://www.cnblogs.com/Hisin/archive/2012/02/27/2370636.html3、对话框&CView窗口    对话框可以分为模式对话框和非模式对话框两种。模式对话框是指用户只能在当前的窗体中进行操作,在该窗体没有关闭之前不能切换到其他的窗体。非模式对话框是指当前的所操作的窗体可以切换。
    CView窗口和对话框之间的区别……4、MFC EDIT控件中改变背景色和文字颜色     //nCtlColor是控件类型  pWnd是指向特定控件    switch(nCtlColor)    {    case CTLCOLOR_EDIT:                      //EDIT编辑框控件        switch(pWnd->GetDlgCtrlID())        //把CWnd指针转换成控件ID        {        case IDC_USERNAME:            pDC->SetBkColor(RGB(0,0,0));   //背景色            pDC->SetTextColor(RGB(0,255,0));//字体颜色            //hbr = (HBRUSH) m_hRedBrush.CreateSolidBrush(RGB(255,0,0));  //更新笔刷            break;        }        break;    }
5、为了防止用户定义的消息ID与系统的消息ID冲突,MS(Microsoft)定义了一个宏WM_USER,小于WM_USER的ID被系统使用,大于WM_USER的ID被用户使用。

6、编辑框的垂直滚动条显示最后一行内容
当文本内容超出控件大小时出现垂直滚动条,显示的是文本上面的内容改成显示最下面的内容:
CEdit *ce=((CEdit*)GetDlgItem(IDC_EDIT3));
ce->LineScroll(ce->GetLineCount()-1);;

7、CSocket中的OnReceive、OnAccept
使用之前可以考虑先重载,方法如下:
class MySocket: public CSoket{  void OnReceive( int nErrorCode );} void MySocket::OnReceive( int nErrorCode ){//重载} 在客户端调用connect的时候服务端就会相应OnReceive;一方调用Send的时候对方就会响应OnAccept;8、DoDataExchange的理解
DoDataExchange函数其实是一项数据动态绑定技术。比如你在写动态按扭过程中须对按钮添加变量时,怎么添加?控件类已经写好了,其变量是已经固定的。你要添加新的变量就要用到DoDataExchange函数。 所以你要在对话框的构造函数里面初始化一个变量,再用DoDataExchange函数将它绑定到你的动态按扭中,比如:DDX_Check(pDX, IDC_CHECK1, m_Lesson1);这就是将m_Lesson1(这是一个外部变量,其定义在对话框的构造函数里)绑定到IDC_CHECK1中。 看下DDX_Check函数原型:void AFXAPI DDX_Check(CDataExchange* pDX, int nIDC, int& value);可以看到m_Lesson并不是真的添加到IDC_CHECK1控件里了,注意这是int& value,只是一个值引用而已。差不多的意思就是这个变量被框架传递给控件了。控件只负责使用此变量 ,而不负责改写此变量。-.- DoDataExchange函数是被框架与控件用来交流数据的。而里面的DDX函数才是动态绑定技术。 (来源:百度知道)9、MFC的CWinApp的两个虚函数InitApplication负责每个程序只做一次,InitInstance负责每一个例程都得做一次;
CThreadDlg* m_Thread=new CThreadDlg();    调用这句话时会调用CThreaDlg的构造函数;







   

原创粉丝点击