搜索
bottom↓
回复: 23

VC++6.0问题:一个类中调用另外一个类的变量的好多种用法

[复制链接]

出90入0汤圆

发表于 2018-9-19 19:45:31 | 显示全部楼层 |阅读模式
CHSCommDlg类 主对话框,有一个“帮助”按钮,点击弹出一个非模态对话框CHelpDlg类

CHSCommDlg类有一个变量 m_bHelpOpen,  在CHelpDlg类要清为FALSE,

请教,以下CHelpDlg类要清为FALSE,有的为什么不行?

void CHelpDlg::PostNcDestroy()
{
        // TODO: Add your specialized code here and/or call the base class
        CDialog::PostNcDestroy();

        // 此处执行时,m_nFlags在模态时已经清零(非模态时不变),故要m_bDlgModal,而不能用m_nFlags判断
//        if(!(m_nFlags & WF_MODALLOOP))
        if(!m_bDlgModal)
        {                // 非模态对话框
                delete this;                        // 释放this指针的内存(非模态对话框)

                // 1, 全局变量                                        OK
//                m_bHelpOpen = FALSE;
               
                // 2, 全局函数 + 全局变量                        OK
                // 3, 全局函数 + public成员变量                编译错误:error C2065: 'm_bHelpOpen' : undeclared identifier
//                Clean_bHelpOpen();                                       

               

                // 4, 成员函数 + public成员变量                编译无错误,但没有赋值
                CHSCommDlg dlg;                                               
                dlg.Set_bHelpOpen(FALSE);

                // 5, 成员函数 + public成员变量                编译错误:error C2143: syntax error : missing ';' before '.'
//                CHSCommDlg.Set_bHelpOpen(FALSE);       

                // 6, public成员变量                                编译无错误,但没有赋值
//                CHSCommDlg dlg;                                       
//                dlg.m_bHelpOpen = FALSE;

                // 7, public成员变量                                编译错误:error C2143: syntax error : missing ';' before '.'
//                CHSCommDlg.m_bHelpOpen = FALSE;               
        }
}



内有 模态/非模态对话框自动判断程序,调试通过的啊

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出90入0汤圆

 楼主| 发表于 2018-9-20 07:36:09 | 显示全部楼层
不知道是不是什么地方设置不对?

出90入0汤圆

 楼主| 发表于 2018-9-20 09:37:23 | 显示全部楼层
最好用以下的,
用Get_xxxxx()和Set_xxxx()  
实现整个工程 零全局变量

                //  成员函数 + private成员变量                编译无错误,但没有赋值       
                CHSCommDlg dlg;                                               
                dlg.Set_bHelpOpen(FALSE);

                // 成员函数 + private成员变量                编译错误:error C2143: syntax error : missing ';' before '.'               
                CHSCommDlg.Set_bHelpOpen(FALSE);

出110入93汤圆

发表于 2018-9-20 09:44:36 | 显示全部楼层
hzpyl 发表于 2018-9-20 09:37
最好用以下的,
用Get_xxxxx()和Set_xxxx()  
实现整个工程 零全局变量

SOILD原则,减少全局变量。

出90入0汤圆

 楼主| 发表于 2018-9-20 11:04:12 | 显示全部楼层
刚刚学习 VC++6.0

编译错误:error C2143: syntax error : missing ';' before '.'   

不知道怎么解决?

出90入0汤圆

 楼主| 发表于 2018-9-20 19:40:55 | 显示全部楼层
有没有 大牛 遇到过这个问题?
点拨一下。

出0入0汤圆

发表于 2018-9-21 08:16:55 | 显示全部楼层
手机上看不到你zip里的东西,不过调用类的静态方法的语法是

XXClass::YYFunction();

出0入0汤圆

发表于 2018-9-21 08:49:29 | 显示全部楼层
没有装vs, 纯看了一下代码,我有以下几个疑问:
1.             //  成员函数 + private成员变量                编译无错误,但没有赋值        
                CHSCommDlg dlg;                                                
                dlg.Set_bHelpOpen(FALSE);
================================
没赋值,是因为此处的dlg, 并不是之前的CHSCommDlg对象。

2.    // 成员函数 + private成员变量                编译错误:error C2143: syntax error : missing ';' before '.'               
                CHSCommDlg.Set_bHelpOpen(FALSE);  
========================================================
CHSCommDlg是个类名, 但你这种写法,让系统认为CHSCommDlg是个对象

3.  CHSCommDlg::OnBUTTONHelp()代码中,CHelpDlg *pDlg=new CHelpDlg(); ,    你是动态new了一个对象,退出此函数后,此对象消失。

4. 大概想了一下你的需求,其实,只要在CHSCommDlg类中,增加一个CHelpDlg类的数据成员,则一切问题就可化解。

另外,从抽象上来说,你这种用法有些问题: 首先,汽车(CHSCommDlg)里面有个轮子(CHelpDlg), 轮子里面却又有个汽车。 何不只让汽车里面有轮子。 就算这二类没有从属上的关系,当两者互相交互时,应该是“get"到一个之前的对象,而不是重新建一个新的对象,因为新对象并不是彼对象。

出0入0汤圆

发表于 2018-9-21 09:12:18 | 显示全部楼层
想在子窗口中,修改父窗口的变量,一般用这2种方法:
1、把父窗口的指针传给子窗口,然后子窗口中直接调用成员函数,或者操作成员变量
2、向父窗口发送自定义消息,父窗口响应消息做对应的修改


在子窗口中,又生成一个父窗口的实例,其实它和真正的父窗口只是同一类型,并无直接关系

另外,Set和Get方法操作类的成员变量,封装性好,但也没必要过度使用

出0入0汤圆

发表于 2018-9-21 09:40:47 来自手机 | 显示全部楼层
McuPlayer 发表于 2018-9-21 09:12
想在子窗口中,修改父窗口的变量,一般用这2种方法:
1、把父窗口的指针传给子窗口,然后子窗口中直接调用 ...

同意,一般用传指针或把类当做结构体来用,初始化类对象时设为外部变量

出0入0汤圆

发表于 2018-9-21 09:53:32 | 显示全部楼层
CHSCommDlg类的变量 m_bHelpOpen声明为静态试试,
用static 关键字。

出90入0汤圆

 楼主| 发表于 2018-9-21 10:34:31 | 显示全部楼层
本帖最后由 hzpyl 于 2018-9-21 13:12 编辑
GoingDown 发表于 2018-9-21 08:49
没有装vs, 纯看了一下代码,我有以下几个疑问:
1.             //  成员函数 + private成员变量           ...


汽车(CHSCommDlg)里面有个轮子(CHelpDlg), 轮子里面却又有个汽车。 何不只让汽车里面有轮子。 就算这二类没有从属上的关系,当两者互相交互时,应该是“get"到一个之前的对象,而不是重新建一个新的对象,因为新对象并不是彼对象。

你这个比喻,使我茅塞顿开。

是不是像about对话框一样,合到CHSCommDlg中去?

m_bHelpOpen变量是定义在CHSCommDlg类的,表示Help对话框是不是打开了。
我在Help对话框销毁的时候,把m_bHelpOpen置FALSE,
就是这个置FALSE的操作不行。

出0入0汤圆

发表于 2018-9-21 14:11:46 | 显示全部楼层
hzpyl 发表于 2018-9-21 10:34
汽车(CHSCommDlg)里面有个轮子(CHelpDlg), 轮子里面却又有个汽车。 何不只让汽车里面有轮子。 就算这二 ...

是的,我就是这个意思。 另外,上面有位网友说的方法,也可以试一下。

出90入0汤圆

 楼主| 发表于 2018-9-21 14:32:23 | 显示全部楼层
McuPlayer 发表于 2018-9-21 09:12
想在子窗口中,修改父窗口的变量,一般用这2种方法:
1、把父窗口的指针传给子窗口,然后子窗口中直接调用 ...

把父窗口的指针传给子窗口,然后子窗口中直接调用成员函数,或者操作成员变量

请问,用什么函数?能举个例子吗?

出0入0汤圆

发表于 2018-9-21 14:37:00 | 显示全部楼层
本帖最后由 McuPlayer 于 2018-9-21 14:42 编辑

class CHelpDlg
{
      CDialog*  m_pParent;
}

void CMainDlg::DoHelp()
{
    CHelpDlg dlg;
    dlg.m_pParent = this;
    dlg.doModule();
}

void CHelpDlg::DoSometingForParent()
{
      CMainDlg* pParent = (CMainDlg*)m_pParent;
      pParent->aaaaaa = 55;

}

出90入0汤圆

 楼主| 发表于 2018-9-21 15:43:25 | 显示全部楼层
本帖最后由 hzpyl 于 2018-9-21 15:45 编辑
McuPlayer 发表于 2018-9-21 14:37
class CHelpDlg
{
      CDialog*  m_pParent;


先谢谢你。
我已经测试:你的这种可以实现。

缺点是: 需要一个Public(private不行)的变量m_pParent,来保存母对话框的指针。

有没有办法从ID号得到指针?

出0入0汤圆

发表于 2018-9-21 15:54:07 | 显示全部楼层
ID号显然是不行的,因为Dialog的对话框ID是模板ID,可以多个对话框实例用同一个ID的
Dialog的句柄倒是唯一的,不过,仍需要一个变量来保存

出90入0汤圆

 楼主| 发表于 2018-9-21 16:03:14 | 显示全部楼层
McuPlayer 发表于 2018-9-21 15:54
ID号显然是不行的,因为Dialog的对话框ID是模板ID,可以多个对话框实例用同一个ID的
Dialog的句柄倒是唯一 ...

请问,你编程时,全局变量用的多吗?

出0入0汤圆

发表于 2018-9-21 16:07:56 | 显示全部楼层
那个是成员变量,不是全局变量,这类变量必须挺多才能实现具体功能

出90入0汤圆

 楼主| 发表于 2018-9-21 16:14:34 | 显示全部楼层
我不是指m_pParent。

用全局变量的话,整个工程都可以读写。
但据高手说,比较危险。
建议使用 Getxxxx() Setxxxx(),至少可以进行类型安全检查,操作条件限制等。都比直接public变量强。

出90入0汤圆

 楼主| 发表于 2018-9-21 16:53:37 | 显示全部楼层
GoingDown 发表于 2018-9-21 14:11
是的,我就是这个意思。 另外,上面有位网友说的方法,也可以试一下。


我把CHelpDlg,与CAboutDlg一样,合到CHSCommDlg中,
还是与原来一样的报警。

文件少了2个,但ClassView上还是分成3个的
CAboutDlg
CHelpDlg
CHSCommDlg

出0入0汤圆

发表于 2018-9-21 17:30:36 | 显示全部楼层
hzpyl 发表于 2018-9-21 16:53
我把CHelpDlg,与CAboutDlg一样,合到CHSCommDlg中,
还是与原来一样的报警。

没看懂你意思, 也可以这样:
添加一个ChelpDlg构造函数:

CHelpDlg(CHSCommdlg *pCHS);

在创建ChelpDlg对象时,把CHSCOmmdlg对象传进去。

出90入0汤圆

 楼主| 发表于 2018-9-25 07:44:38 | 显示全部楼层
祝 中秋节快乐!

中秋节都在试这个问题,终于得到最佳答案:
CHSCommDlg *pP = (CHSCommDlg*)GetParent();        // 如果方法成功,则标识父窗口。否则,该值为NULL,指示错误或父窗口。
pP->Set_bHelpOpen(FALSE);

出90入0汤圆

 楼主| 发表于 2018-9-25 15:51:26 | 显示全部楼层
用静态变量和静态函数,也可以:
                               静态变量
1,在CHSCommDlg.h中,定义静态变量 static bool m_bHelpOpen; ,需要public,定义在private不行
2,在CHSCommDlg.cpp中初始化,bool CHSCommDlg::m_bHelpOpen = FALSE;
3,CHelpDlg中,用 CHSCommDlg::m_bHelpOpen = FALSE;        //  静态变量

                           静态函数
1,在CHSCommDlg.h中,定义静态变量 static bool m_bHelpOpen; ,定义在private
                     定义静态函数static void Set_bHelpOpen(bool sign);  ,需要public,定义在private不行
2,在CHSCommDlg.cpp中初始化,bool CHSCommDlg::m_bHelpOpen = FALSE;
   函数 void CHSCommDlg::Set_bHelpOpen(bool sign)
        {
                m_bHelpOpen = sign;
        }
3,CHelpDlg中,用 CHSCommDlg::Set_bHelpOpen(FALSE);        //  静态函数
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-26 12:47

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表