hzpyl 发表于 2018-9-19 19:45:31

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

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;               
        }
}



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

hzpyl 发表于 2018-9-20 07:36:09

不知道是不是什么地方设置不对?

hzpyl 发表于 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);

memstone 发表于 2018-9-20 09:44:36

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


SOILD原则,减少全局变量。

hzpyl 发表于 2018-9-20 11:04:12

刚刚学习 VC++6.0

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

不知道怎么解决?{:cry:}

hzpyl 发表于 2018-9-20 19:40:55

有没有 大牛 遇到过这个问题?
点拨一下。

Scarlette 发表于 2018-9-21 08:16:55

手机上看不到你zip里的东西,不过调用类的静态方法的语法是

XXClass::YYFunction();

GoingDown 发表于 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"到一个之前的对象,而不是重新建一个新的对象,因为新对象并不是彼对象。

McuPlayer 发表于 2018-9-21 09:12:18

想在子窗口中,修改父窗口的变量,一般用这2种方法:
1、把父窗口的指针传给子窗口,然后子窗口中直接调用成员函数,或者操作成员变量
2、向父窗口发送自定义消息,父窗口响应消息做对应的修改


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

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

hkjabcd 发表于 2018-9-21 09:40:47

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

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

lbn2006 发表于 2018-9-21 09:53:32

CHSCommDlg类的变量 m_bHelpOpen声明为静态试试,
用static 关键字。

hzpyl 发表于 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的操作不行。

GoingDown 发表于 2018-9-21 14:11:46

hzpyl 发表于 2018-9-21 10:34
汽车(CHSCommDlg)里面有个轮子(CHelpDlg), 轮子里面却又有个汽车。 何不只让汽车里面有轮子。 就算这二 ...

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

hzpyl 发表于 2018-9-21 14:32:23

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

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

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

McuPlayer 发表于 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;

}

hzpyl 发表于 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号得到指针?

McuPlayer 发表于 2018-9-21 15:54:07

ID号显然是不行的,因为Dialog的对话框ID是模板ID,可以多个对话框实例用同一个ID的
Dialog的句柄倒是唯一的,不过,仍需要一个变量来保存

hzpyl 发表于 2018-9-21 16:03:14

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

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

McuPlayer 发表于 2018-9-21 16:07:56

那个是成员变量,不是全局变量,这类变量必须挺多才能实现具体功能

hzpyl 发表于 2018-9-21 16:14:34

我不是指m_pParent。

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

hzpyl 发表于 2018-9-21 16:53:37

GoingDown 发表于 2018-9-21 14:11
是的,我就是这个意思。 另外,上面有位网友说的方法,也可以试一下。

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

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

GoingDown 发表于 2018-9-21 17:30:36

hzpyl 发表于 2018-9-21 16:53
我把CHelpDlg,与CAboutDlg一样,合到CHSCommDlg中,
还是与原来一样的报警。



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

CHelpDlg(CHSCommdlg *pCHS);

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

hzpyl 发表于 2018-9-25 07:44:38

祝 中秋节快乐!

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

hzpyl 发表于 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);        //静态函数
页: [1]
查看完整版本: VC++6.0问题:一个类中调用另外一个类的变量的好多种用法