软件水平考试频道  水平考试 等级考试 微软认证 思科认证 Oracle认证 Linux认证 Java认证
    考试动态 | 报考指南 | 考试大纲 | 历年真题 | 模拟试题 | 经验交流 | 计算机专业英语
网络管理员 | 网络工程师 | 程序员 | 软件设计师 | 系统分析师 | 信息系统项目管理师 | 信息系统监理师 | 软件评测师
数据库系统工程师 | 电子商务设计师 | 电子商务技术员 | 信息技术处理员 | 系统架构设计师 | 标准化知识 | 法律法规知识
谈谈c++的初始化工作(2) 
谈谈c++的初始化工作(2)
http://www.HHxue.com 好好学-软件水平考试频道 更新时间: 2006-8-8 上午 08:48:37

/p>

  我们首先来看上次遗留的问题。
把(1)中的代码换为注释部分,或许您一时还认识不到会有什么发生,但最终是通不过的,调试抛出异常,信息如下:
未处理的“System.Runtime.InteropServices.SEHException”类型的异常出现在 TestInit.exe 中

其他信息:外部组件发生异常。

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
Press any key to continue

我想,您回头再细看的话,就会明白为什么如此了(我们写程序一定要追问到底:)。

我们今天要谈的是,一些变量只有唯一的初始化形式,通过例子,告诉您要特别注意。然后,我们就一步一步,来看资源浅拷贝的问题。我相信初学c++的同学,会对“拷贝函数”有些疑问,它就是为了解决上述问题的;但事实上,还有一个隐藏的地方,今天我也想给您指出。
这些程序,可是我特意设计的哦。希望可以很方便的认识问题所在,与解决之道。

首先,看第一个例子。在类中,这两类变量:
e.g.
Name &name; //引用
const int ID; //常量
它们的初始化形式是唯一的。而且必须由您来初始化。
看下面的程序:

//human.h
#pragma once

class Name
{
char *name;
public:
//...
};
class Human
{
Name &name;
const int ID;//每个人都唯一的标志号
//...
public:
Human(void);
~Human(void);

//...
};
//human.cpp
#include "human.h"
#using <mscorlib.dll>

//默认的构造函数
Human::Human(void)
{
}

Human::~Human(void)
{
}

写一个主文件测试。
但调试出错,错误信息文件为:
/*----------------------------------------------------------------------------
//Human:error file
------ 已启动生成:项目:TestInit, 配置:Debug Win32 ------

正在编译...
Human.cpp
Human.cpp(5) : error C2758: “Human::name” : 必须在构造函数基/成员初始值设定项列表中初始化
e:NETSmall_codeTestInitHuman.h(13) : 参见“Human::name”的声明
Human.cpp(5) : error C2758: “Human::ID” : 必须在构造函数基/成员初始值设定项列表中初始化
e:NETSmall_codeTestInitHuman.h(14) : 参见“Human::ID”的声明
fmain.cpp
Date.cpp
正在生成代码...

生成日志保存在“file://e:NETSmall_codeTestInitDebugBuildLog.htm”中
TestInit - 2 错误,0 警告


---------------------- 完成 ---------------------

生成:0 已成功, 1 已失败, 0 已跳过
--------------------------------------------------------------------------------
*/

因为这里涉及的是仅仅的c++语法,我就不多费口舌了,如何改正,希望您能动手试试,一定要动手,不要想当然哦~~~
当然,如果您是爱问题的人,我想您可以这样深究一下:设计c++语言时,为什么诸如int类型成员变量能提供默认初始化,而它们却不能;从编译角度,刻意给它们提供如int类型般的初始化会有什么困难和问题?


下面详细谈什么是资源浅拷贝问题。沿袭c的习惯,c++对系统自分配的资源进行统一管理,但是,用户申请的资源,则有用户来释放。
比如:

userType *p=new userType(/*---*/);
//...
delete p;
//delete释放一般是不可忘的

单独的变量或许对您来说是不成问题的。但在类中,这些情况就变的相当复杂。处理不好,您的系统要么就是因为内存泄露而运行不下去,而要么就是异常频频发生。
我们先来看一些c++的默认操作:
//...
class OneClass {
int _value;
public:
OneClass(int _val=0):_value(_val) {}
~OneClass() {}

//...
};

//you may use in this way:
OneClass oneObj(7);
OneClass anotherObj;
anotherObj=oneObj;//(1)
//...
//int Compare(OneClass one,OneClass two);
int k=Compare(oneObj,anotherObj);//(2)
//...

在本程序的场景下,上面的代码是可以完好工作的,但您清楚(1)与(2)系统都作了什么了吗?您是否知道,如果您的初始化工作做的不好的话,即使,就沿用上面的初始化习惯,您的程序很容易就崩溃了呢。
答案是,(1)语句执行时,默认的,系统试图把oneObj的资源全部copy给anotherObj,但用户申请的资源(new来的:),却传入的是地址;(2)语句的默认形参传递遵循同样的规则。
当然这与java与c#是不同的,因为java与c#的对象是引用类型。而c++,除非您强行定义为引用类型的,它就不是。

我们来看下面的例子,第一遍我建议您只看程序,不要往下看,看您能否发现什么问题。

//human.h
#pragma once

#define NULL 0

class Name
{
char *name;
public:
Name(char *_name=NULL):name(_name) {}
~Name() { }

char *getName(){ return name;}

};
class Human
{
Name *name;//
int ID; //唯一化标志
public:
Human(int id=0,char *_name=NULL);
~Human(void);

[1] [2] [3] 下一页

文章录入:HHxue.com    责任编辑:好好学   
  • 上一篇文章:

  • 下一篇文章: 没有了
  •  版权声明
       如果本网站所转载内容不慎侵犯了您的权益,请与我们联系stephen5514@sina.com.cn,我们将会及时处理。如转载本站内容,请注明出处。
     发表评论
    没有任何评论
    网站首页 IT 认证 外语考试 资格考试 学历考试 工程考试 硕士学历 财经考试

    好好学版权所有 © 2006-2007 网站首页 | 关于我们 | 联系我们 | 免责声明 | 友情链接 | 招聘英才 |
    客户服务QQ:418260511客户服务邮箱:stephen5514@sina.com.cn
    晋ICP备06005044号 好好学版权所有