面向对象编程安全作业

发布 2023-05-16 23:30:28 阅读 4606

作业1:写一段静态成员不安全的**并对提出解决方案。

具体**见p1_unsafestatic工程,下面对核心**进行分析:

class crabbit

public:

crabbit(){

~crabbit(){

static int our_n_carrot;

void eat()

void collect()

void count_carrot()

这里模拟的是一个兔子的行为,包括吃萝卜、收集萝卜和数萝卜,这里有一个类静态成员变量,表示兔群当前萝卜数。但是,静态变量当被多线程操作时,就会变得很不安全,这里尝试用多只兔子来模拟这个过程。模拟兔子行为的**如下:

bool rabbit_act()

crabbit rabbit;

while (1)

return true;

这里定义的规则是:当一个兔子发现兔群的萝卜数大于0时,它就会吃掉一个萝卜;否则,它会去收集一个萝卜。最后,它会报出当前兔群的萝卜数,如此反复。

最后在主函数中开三个“兔子”线程,观察运行结果如下图所示:

图1-1 程序运行结果示意图。

这里可以看出,某些兔子已经把萝卜吃成负的了……所以直接对类静态变量进行修改是存在问题的……这里的解决方案就是每次只允许一个兔子操作萝卜,用一个全局的静态变量进行保护。核心**如下:

if (!crabbit::m_b_busy)

crabbit::m_b_busy = true;

if (crabbit::our_n_carrot > 0)

elsecrabbit::m_b_busy = false;

图1-2 程序运行结果示意图(2)

这里可以看到,如果加了标识变量进行保护时,萝卜的数量始终为0或者1,这样就不会出现问题。

作业2:(1)在c和j**a中怎样**内存?(2)单例模式为什么能提高程序性能?有何劣势?

c语言是使用delete或者free释放内存,delete用于释放new动态申请的空间,free用于释放malloc动态申请的空间。而到了其生命周期的变量,其内存会被自动**。而j**a是调用finalise()是申请**内存,至于何时被**并不能被确定。

单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。

如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。

优点:实例控制,单例模式会阻止其他对象实例化其自己的单例对象的副本,从而确保所有对象都访问唯一实例。灵活性,因为类控制了实例化过程,所以类可以灵活更改实例化过程。

缺点:开销,虽然数量很少,但如果每次对象请求引用时都要检查是否存在类的实例,将仍然需要一些开销。可以通过使用静态初始化解决此问题。

可能的开发混淆,使用单例对象(尤其在类库中定义的对象)时,开发人员必须记住自己不能使用new关键字实例化对象。因为可能无法访问库源**,因此应用程序开发人员可能会意外发现自己无法直接实例化此类。对象生存期,不能解决删除单个对象的问题。

在提供内存管理的语言中(例如基于。net framework的语言),只有单例类能够导致实例被取消分配,因为它包含对该实例的私有引用。在某些语言中(如 c++)其他类可以删除对象实例,但这样会导致单例类**现悬浮引用。

作业3:异常可以就地处理,也可以向客户端传递。

1) 举出两个需要向客户端传递的异常的例子;

无法通过参数检查,例如空值、参数取值范围等,因为参数的规则说明是作为方法签名的一部分发布的,调用者应该很清楚调用这个方法所需要的参数的规格,但是调用者现在传入的错误的参数,说明调用者本身这时候很可能就已经出现问题了。对参数进行检查本身也是一个编写一个方法的良好习惯,这可以保证方法本身在一个相对比较稳定可知道状态下工作,因此方法本身将更简单也更稳定。总之,拒绝非法的参数,并抛出异常。

将可能导致以后的相关功能出错,如果一个异常或者错误的参数将导致以后更多的异常或者以后的某个功能异常,那么不要延迟,立即抛出异常。例如有一个属性filename用来保存将被保存的文件的名称,一个的方法s**e将保存到filename所指定的文件名中去,显然在给filename属性赋值时,如果给出一个包含非法文件名字符的字符串,那么将导致 s**e 方法中会有异常发生,不论 s**e 方法是否对 filename 再进行检查,这时候距离设定filename的**可能已经相当远了,因此在设定filename的时候,就应该要进行这种有关的检查,如果文件名不合法,立即抛出异常,而不要等到以后再来发现这个问题。上述对参数进行检查其实很多也是这种情况,特别一些空值参数,将可能导致以后使用该参数的时候发生空值异常。

2) 举出两个可以就地处理的异常的例子。

从集合中删除指定键值对应的元素,但指定的键值其实并不在集合中。这显然是一个意外情况,但是,就此继续下去,以后的程序应该还可以继续有效的运行,因为即使在正常情况下也不过是这个元素不再存在于集合中而已。返回一个整数值表示删除掉的元素的个数,如果没有找到给定的元素,则返回0表示没有元素被删除。

这个例子的另一种情形是,当前集合元素因为某种原因被锁住不能删除元素,那么应该抛出一个异常表示删除失败,而不是返回0表示没有删除元素。

用户输入格式不正确,如果能经过处理,使得可以正常读人,不影响后门的程序运行,就可以不必抛出异常。

作业4:有一个try块放在for循环内,如果try块内跳出该循环,finally是否会执行?试编程举例。

完整工程见p4_testfinally,核心**和运行结果如下:

for (i=0; i<=5; i++)

trycatch (exception e)

finally

图4-1 程序运行结果。

这里可以看出,虽然运行了break,但是还是会执行1次finally之后,再跳循环。看来finally中的**果然会被执行……【为何c++没有finally……】

作业5:编写一个程序,客户输入一个数字,打印其平方。但是如果出错,程序不断提示客户重新输入,直到他输入正确为止。

详细工程见p5_whiletrue,核心**和运行结果如下图所示:

double d;

bool flag = true;

while (flag)else

图5-1 程序运行结果。

面向对象高级编程作业之一

一 编写一个类student1,代表学员,要求 a 具有属性 姓名 年龄 其中年龄不能小于16岁,否则输出错误信息。b 具有方法 自我介绍,负责输出该学员的姓名 年龄。二 编写一个类student2,代表学员 要求 a 具有属性 姓名 年龄 性别 专业。b 具有方法 自我介绍,负责输出该学员的姓名 ...

面向对象高级编程试题

1 常见的网页不断在服务器端刷新,其弊端一是 二是 三是 2 updatepanel的updatemode共有两种模式,他们是 与 3 linq语言中用于对检索到的数据进行分组的属性是 4 css样式表按其位置的不同可以分为 及 三类。5.每个 都有一个配置文件,其文件名为 6 常量 字符串 甚至任...

面向对象高级编程试题

一 填空题 20空,每空2分,共40分 1 css即 用于增强控制网页样式并允许将样式信息与网页内容分离的一种标记语言。2 linq的目标是以 的方式,直接利用 访问各种不同类型的数据。3 updatepanel即ajax的面板,页面中所使用的ajax控件必须放在 控件中,才能发挥其作用。编写的we...