很急的一个问题:在VC中,类外使用类的受保护函数,我使用了继承(直接在VC里使用类继承的格式),但是出现了错误···

时间:2021-07-08 19:30:27
具体内容:
用VC生成一个基于对话框的程序
为了使该程序可以实现对文件的操作(如往编辑框/EditBox里面输入数字,运行程序可以实现输入的数字保存在文本文件内)
我知道在VC中Serialize(CArchive& ar)函数可以实现这个功能(它只在文档类中才有?)
于是我添加了基于文档类的类,想利用继承该类使用Serialize(CArchive& ar)函数

现在的问题是:我直接在VC里使用了一个类继承另一个类(不知道VC里有没有选项可以间接实现这个功能?),但是编译的时候出现了一些没见过的错误

后来我又用友员类试图实现这个功能,但同样出现了错误,只不过是出现了:提示我去查看Serialize(CArchive& ar)函数的定义

想问:1:如何实现该类继承基于对话框的类 或对话框的类 继承基于文档类的类
       2:能否用友员类实现这个功能,该怎么实现
       3:VC的选项设置里面有没让一个类继承另外一个类的选项或让一个类成为另外一个类的友员类

很急···

12 个解决方案

#1


你怎么继承的?帖上代码看看,友员自己加一下啊

#2


它只在文档类中才有?你自己做个对象也行,或者直接用I/O API
不知道VC里有没有选项可以间接实现这个功能?
你的问题和通常的C++类相继承是一样的,VC中也大同小异,你没有必要用文档类,自己做序列化处理,用不着用友元。

#3


用VC生成一个基于对话框的程序
为了使该程序可以实现对文件的操作(如往编辑框/EditBox里面输入数字,运行程序可以实现输入的数字保存在文本文件内)

有没有其他方法可以实现我要的这个功能?能不能详细的说一下。

#4


Serialize(CArchive& ar)并不只在文档类中存在了

#5


To : yzx0023(无聊客),就是直接用class a:public b{}语法直接继承
编译时出现了几个没有来由的错误·


To:mscf(扎西特勒) ,第一次写VC程序,“自己做序列化处理,用不着用友元。”不懂什么是序列化,能不能帮我具体解释一下。另外还有没有起他方法可以实现这个功能?能不能具体的帮我解释如何实现我要的功能。中午就要提交了,所以很急···谢谢了
我的邮箱是maoshaxu@163.com  能帮我做个实例发给我最好了。
分不够我可以再添·

#6


在对话框类里面没有呀

#7


用VC生成一个基于对话框的程序
为了使该程序可以实现对文件的操作(如往编辑框/EditBox里面输入数字,运行程序可以实现输入的数字保存在文本文件内)
--------------------------------------------------------------------------

可以的啊~~~
你可以自己写个读写txt文件的类啊 很简单的~~~ 比如:class CTxtFile : public CFile

定义读写函数:

public:
      .................
      //主要的读写函数
      bool ReadTxtFile(  );
      bool WriteTxtFile(  );
      .................
然后把CTxtFile txtFile; 声明成你的继承自CDialog类的public成员就可以了~~~

#8


能具体说下函数的功能吗?(如我在编辑框里输入1234567889)如何用WriteTxtFile
使之输出到**.txt里//能用具体的代码最好了

第一写VC程序,很多函数都不知道

#9


你和 边城浪子 什么关系?

#10


名字类似
仅此而已

#11


序列化在最低的层次上应该被需要序列化的类支持,也就是说如果你需要对一个类进行序列化,那么这个类必须支持序列化。当通过序列化进行文件读写时你只需要该类的序列化函数就可以了。

怎样使类具有序列化功能呢?你需要以下的工作: 

该类从CObject派生。 
在类声明中包括DECLARE_SERIAL宏定义。 
提供一个缺省的构造函数。 
在类中实现Serialze函数 
使用IMPLEMENT_SERIAL指明类名和版本号 

下面的代码建立了一个简单身份证记录的类,同时也能够支持序列化。 

in H
struct strPID
{
char szName[10];
char szID[16];
struct strPID* pNext;
};
class CAllPID : public CObject
{
public:
DECLARE_SERIAL(CAllPID)
CAllPID();
~CAllPID();

public:// 序列化相关
struct strPID* pHead;
//其他的成员函数
void Serialize(CArchive& ar);
};

in CPP
IMPLEMENT_SERIAL(CAllPID,CObject,1) // version is 1,版本用于读数据时的检测
void CAllPID::Serialize(CArchive& ar)
{
int iTotal;
if(ar.IsStoring())
{//保存数据
iTotal=GetTotalID();//得到链表中的记录数量
arr<>iTotal;
for(int i=0;i>*(((BYTE*)pID)+j);//读一个strPID中所有的数据
//修改链表
}
}
}

当然上面的代码很不完整,但已经可以说明问题。这样CAllPID就是一个可以支持序列化的类,并且可以根据记录的数量动态分配内存。在序列化中我们使用了CArchive类,该类用于在序列化时提供读写支持,它重载了<<和>>运算符号,并且提供Read和Write函数对数据进行读写。 

下面看看如何在文档中使用序列化功能,你只需要修改文档类的Serialize(CArchive& ar)函数,并调用各个进行序列化的类的Serial进行数据读写就可以了。当然你也可以在文档类的内部进行数据读写,下面的代码利用序列化功能读写数据:

class CYourDoc : public CDocument
{
void Serialize(CArchive& ar);
CString m_szDesc;
CAllPID m_allPID;
......
}

void CYourDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{//由于CString对CArchive定义了<<和>>操作符号,所以可以直接利用>>和<<
ar<>m_szDesc;
}
m_allPID.Serialize(ar);//调用数据类的序列化函数
}

#12


不管怎么样

谢谢大家的关注


这里还有个问提

void CLotteryDlg::OnGenerate() 
{
// TODO: Add your control notification handler code here
//m_Pw="这是一个测试";
      
 
UpdateData(TRUE);
//for(j=1;j<=1000;j++)
// {
    a=atof(m_Num7);//*2+1;//这是新的编辑框
b=atof(m_Num8);//*2+11;
c=atof(m_Num9);//+4)*2;
d=atof(m_Num10);//*2+16;
e=atof(m_Num11);//+5)*2;
f=atof(m_Num12);//+7)*2;
  ofstream f2("Lottery.txt",ios::out|ios::trunc);
  if(!f2){
  MessageBox("Lottery不存在请创建");
  exit(1);}

      for(j=1;j<=1000;j++)
{  
   

        u=rand()%49-a;//用一个随机数减去输入的数,如果得到数的范围在1~49之间,则取输入的数a,
//如果不是,则去u
        if(u>=1&&u<=49)
        m_Num1=a;
else
m_Num1=u;


v=rand()%49-b;
 if(v>=1&&v<=49)
        m_Num2=b;
else
m_Num2=v;


w=rand()%49-c;
 if(w>=1&&w<=49)
        m_Num3=c;
else
m_Num3=w;
 

 x=rand()%49-d;
 if(x>=1&&x<=49)
        m_Num4=d;
else
m_Num4=x;


y=rand()%49-e;
 if(y>=1&&y<=49)
       m_Num5=e;
else
m_Num5=y;


z=rand()%49-f;
 if(z>=1&&z<=49)
        m_Num6=f;
else
m_Num6=z;
        
 
if(a>=1&&a<=15)
m_Pw1=u*u+101;
else if(u>=16&&u<=41)
m_Pw1=u*2+4;
else if(u>=42&&u<=49)
m_Pw1=(u-40);


if(v>=1&&v<=18)
m_Pw2=v*3+40;
else if(v>=19&&v<=40)
m_Pw2=b*5+77;
else if(v>=41&&v<=49)
m_Pw2=v-40;




if(w>=1&&w<=17)
m_Pw3=w*22+100;
else if(w>=18&&w<=27)
m_Pw3=w-18;
else if(w>=28&&w<=49)
m_Pw3=w*2-5;




if(x>=1&&x<=2)
m_Pw4=x*4;
else if(x>=3&&x<=18)
m_Pw4=(x+4)*3;
else if(x>=19&&x<=49)
m_Pw4=x*16+13;




if(y>=1&& y<=16)
m_Pw5=y*y+375;
else if(y>=17&&y<=41)
m_Pw5=y*2-10;
else if(y>=42&&y<=49)
m_Pw5=y-41;



if(z>=1&&z<=8)
m_Pw6=z*z+30;
else if(z>=9&&z<=15)
m_Pw6=z-6;
else if(z>=16&&z<=49)
m_Pw6=z*15+51;
   

    p[j][1]=m_Num1;
      p[j][2]=m_Num2;
      p[j][3]=m_Num3;
     p[j][4]=m_Num4;
       p[j][5]=m_Num5;
       p[j][6]=m_Num6;
      //p[j][7]=" ";
      p[j][8]=m_Pw1;
      p[j][9]=m_Pw2;
       p[j][10]=m_Pw3;
       p[j][11]=m_Pw4;
      p[j][12]=m_Pw5;
      p[j][13]=m_Pw6;

  



  f2<<j<<p[j][1]<<p[j][2]<<p[j][3]<<p[j][4]<<p[j][5]<<p[j][6];
  f2<<p[j][8]<<p[j][9]<<p[j][10]<<p[j][111]<<p[j][12]<<p[j][13]<<"\n";
 
  f2.close();




            
    
 }

 






 
 UpdateData(FALSE);
}

#1


你怎么继承的?帖上代码看看,友员自己加一下啊

#2


它只在文档类中才有?你自己做个对象也行,或者直接用I/O API
不知道VC里有没有选项可以间接实现这个功能?
你的问题和通常的C++类相继承是一样的,VC中也大同小异,你没有必要用文档类,自己做序列化处理,用不着用友元。

#3


用VC生成一个基于对话框的程序
为了使该程序可以实现对文件的操作(如往编辑框/EditBox里面输入数字,运行程序可以实现输入的数字保存在文本文件内)

有没有其他方法可以实现我要的这个功能?能不能详细的说一下。

#4


Serialize(CArchive& ar)并不只在文档类中存在了

#5


To : yzx0023(无聊客),就是直接用class a:public b{}语法直接继承
编译时出现了几个没有来由的错误·


To:mscf(扎西特勒) ,第一次写VC程序,“自己做序列化处理,用不着用友元。”不懂什么是序列化,能不能帮我具体解释一下。另外还有没有起他方法可以实现这个功能?能不能具体的帮我解释如何实现我要的功能。中午就要提交了,所以很急···谢谢了
我的邮箱是maoshaxu@163.com  能帮我做个实例发给我最好了。
分不够我可以再添·

#6


在对话框类里面没有呀

#7


用VC生成一个基于对话框的程序
为了使该程序可以实现对文件的操作(如往编辑框/EditBox里面输入数字,运行程序可以实现输入的数字保存在文本文件内)
--------------------------------------------------------------------------

可以的啊~~~
你可以自己写个读写txt文件的类啊 很简单的~~~ 比如:class CTxtFile : public CFile

定义读写函数:

public:
      .................
      //主要的读写函数
      bool ReadTxtFile(  );
      bool WriteTxtFile(  );
      .................
然后把CTxtFile txtFile; 声明成你的继承自CDialog类的public成员就可以了~~~

#8


能具体说下函数的功能吗?(如我在编辑框里输入1234567889)如何用WriteTxtFile
使之输出到**.txt里//能用具体的代码最好了

第一写VC程序,很多函数都不知道

#9


你和 边城浪子 什么关系?

#10


名字类似
仅此而已

#11


序列化在最低的层次上应该被需要序列化的类支持,也就是说如果你需要对一个类进行序列化,那么这个类必须支持序列化。当通过序列化进行文件读写时你只需要该类的序列化函数就可以了。

怎样使类具有序列化功能呢?你需要以下的工作: 

该类从CObject派生。 
在类声明中包括DECLARE_SERIAL宏定义。 
提供一个缺省的构造函数。 
在类中实现Serialze函数 
使用IMPLEMENT_SERIAL指明类名和版本号 

下面的代码建立了一个简单身份证记录的类,同时也能够支持序列化。 

in H
struct strPID
{
char szName[10];
char szID[16];
struct strPID* pNext;
};
class CAllPID : public CObject
{
public:
DECLARE_SERIAL(CAllPID)
CAllPID();
~CAllPID();

public:// 序列化相关
struct strPID* pHead;
//其他的成员函数
void Serialize(CArchive& ar);
};

in CPP
IMPLEMENT_SERIAL(CAllPID,CObject,1) // version is 1,版本用于读数据时的检测
void CAllPID::Serialize(CArchive& ar)
{
int iTotal;
if(ar.IsStoring())
{//保存数据
iTotal=GetTotalID();//得到链表中的记录数量
arr<>iTotal;
for(int i=0;i>*(((BYTE*)pID)+j);//读一个strPID中所有的数据
//修改链表
}
}
}

当然上面的代码很不完整,但已经可以说明问题。这样CAllPID就是一个可以支持序列化的类,并且可以根据记录的数量动态分配内存。在序列化中我们使用了CArchive类,该类用于在序列化时提供读写支持,它重载了<<和>>运算符号,并且提供Read和Write函数对数据进行读写。 

下面看看如何在文档中使用序列化功能,你只需要修改文档类的Serialize(CArchive& ar)函数,并调用各个进行序列化的类的Serial进行数据读写就可以了。当然你也可以在文档类的内部进行数据读写,下面的代码利用序列化功能读写数据:

class CYourDoc : public CDocument
{
void Serialize(CArchive& ar);
CString m_szDesc;
CAllPID m_allPID;
......
}

void CYourDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{//由于CString对CArchive定义了<<和>>操作符号,所以可以直接利用>>和<<
ar<>m_szDesc;
}
m_allPID.Serialize(ar);//调用数据类的序列化函数
}

#12


不管怎么样

谢谢大家的关注


这里还有个问提

void CLotteryDlg::OnGenerate() 
{
// TODO: Add your control notification handler code here
//m_Pw="这是一个测试";
      
 
UpdateData(TRUE);
//for(j=1;j<=1000;j++)
// {
    a=atof(m_Num7);//*2+1;//这是新的编辑框
b=atof(m_Num8);//*2+11;
c=atof(m_Num9);//+4)*2;
d=atof(m_Num10);//*2+16;
e=atof(m_Num11);//+5)*2;
f=atof(m_Num12);//+7)*2;
  ofstream f2("Lottery.txt",ios::out|ios::trunc);
  if(!f2){
  MessageBox("Lottery不存在请创建");
  exit(1);}

      for(j=1;j<=1000;j++)
{  
   

        u=rand()%49-a;//用一个随机数减去输入的数,如果得到数的范围在1~49之间,则取输入的数a,
//如果不是,则去u
        if(u>=1&&u<=49)
        m_Num1=a;
else
m_Num1=u;


v=rand()%49-b;
 if(v>=1&&v<=49)
        m_Num2=b;
else
m_Num2=v;


w=rand()%49-c;
 if(w>=1&&w<=49)
        m_Num3=c;
else
m_Num3=w;
 

 x=rand()%49-d;
 if(x>=1&&x<=49)
        m_Num4=d;
else
m_Num4=x;


y=rand()%49-e;
 if(y>=1&&y<=49)
       m_Num5=e;
else
m_Num5=y;


z=rand()%49-f;
 if(z>=1&&z<=49)
        m_Num6=f;
else
m_Num6=z;
        
 
if(a>=1&&a<=15)
m_Pw1=u*u+101;
else if(u>=16&&u<=41)
m_Pw1=u*2+4;
else if(u>=42&&u<=49)
m_Pw1=(u-40);


if(v>=1&&v<=18)
m_Pw2=v*3+40;
else if(v>=19&&v<=40)
m_Pw2=b*5+77;
else if(v>=41&&v<=49)
m_Pw2=v-40;




if(w>=1&&w<=17)
m_Pw3=w*22+100;
else if(w>=18&&w<=27)
m_Pw3=w-18;
else if(w>=28&&w<=49)
m_Pw3=w*2-5;




if(x>=1&&x<=2)
m_Pw4=x*4;
else if(x>=3&&x<=18)
m_Pw4=(x+4)*3;
else if(x>=19&&x<=49)
m_Pw4=x*16+13;




if(y>=1&& y<=16)
m_Pw5=y*y+375;
else if(y>=17&&y<=41)
m_Pw5=y*2-10;
else if(y>=42&&y<=49)
m_Pw5=y-41;



if(z>=1&&z<=8)
m_Pw6=z*z+30;
else if(z>=9&&z<=15)
m_Pw6=z-6;
else if(z>=16&&z<=49)
m_Pw6=z*15+51;
   

    p[j][1]=m_Num1;
      p[j][2]=m_Num2;
      p[j][3]=m_Num3;
     p[j][4]=m_Num4;
       p[j][5]=m_Num5;
       p[j][6]=m_Num6;
      //p[j][7]=" ";
      p[j][8]=m_Pw1;
      p[j][9]=m_Pw2;
       p[j][10]=m_Pw3;
       p[j][11]=m_Pw4;
      p[j][12]=m_Pw5;
      p[j][13]=m_Pw6;

  



  f2<<j<<p[j][1]<<p[j][2]<<p[j][3]<<p[j][4]<<p[j][5]<<p[j][6];
  f2<<p[j][8]<<p[j][9]<<p[j][10]<<p[j][111]<<p[j][12]<<p[j][13]<<"\n";
 
  f2.close();




            
    
 }

 






 
 UpdateData(FALSE);
}