c++语言程序设计第五版课后题答案

第5章 数据的共享与保护 5-7 定义一个Cat类,拥有静态数据成员 numOfCats,记录Cat的个体数目;静态成员函数getNumOfCats(),读取numOfCats。设计程序测试这个类,体会静态数据成员和静态成员函数的用法。 #include<iostream> using namespace

第5章  数据的共享与保护 

5-7定义一个Cat类,拥有静态数据成员 numOfCats,记录Cat的个体数目;静态成员函数getNumOfCats(),读取numOfCats。设计程序测试这个类,体会静态数据成员和静态成员函数的用法。

#include<iostream>
using namespace std;
 
class cat{
    public:
        cat()
        {
            numOfCats++;
        }
        static int getNumOfCats()
        {
            return numOfCats;
        }
        ~cat()
        {
            numOfCats--;
        }
    private:
        static int numOfCats;
};
int cat::numOfCats = 0;  //类的静态成员变量必须在类外进行初始化
 
void numprintf()
{
	cout<<"There are "<<cat::getNumOfCats()<<" cats alive!"<<endl;
}
 
int main()
{
    cat a;
    cat b;
    cat c;
    numprintf();
    
    cat *t1,*t2;
    t1=new cat();
    t2=new cat();
    numprintf();
    
    delete t1;
    numprintf();
    
    return 0;
}

注:静态数据成员numOfCats用来给cat类的对象个数进行计数,其cat类的所有对象共同维护和使用,数据共享

在类外可通过“类名::静态数据成员标识符”调用静态数据成员,而且类的静态成员变量必须在类外进行初始化,不能在类内进行初始化。

5-11 在一个文件中定义一个全局变量n,主函数main(),在另一个文件中定义函数fn1(),在main()中对n赋值,再调用fn1(),在fn1()中也对n赋值,显示n最后的值。

//main文件
#include<iostream>
using namespace std;

#include"fn1.h"  //声明头文件
int n;
int main()
{	
	n=0;
    fn1();
	cout<<"n的值:"<<n<<endl;
	return 0;
}

//另外建一个名为fn1.h的头文件

extern int n;    //声明外部变量n
int fn1()
{
	n=5;
}

头文件fn1.h里有外部变量n,用extern关键字加以声明,这个外部变量是可以为多个源文件共享的全局变量

PS:main文件中声明需要的文件名称需要和调用的文件名称一致,一一对应,才能调出需要的内容。

5-12 在函数fn1()中定义一个静态变量n,fn1()中对n的值加1,在主函数中,调用fn1()十次,显示n的值。

#include<iostream>
using namespace std;
 
void fun1()
{
    static int n = 0;   //静态变量
    n++;
    cout<<n<<endl;
}
 
int main()
{
    for(int i = 0 ;i < 10 ; i++)
    {
        fun1();
    }
 
    return 0;
}

函数fn1()中的静态变量n会保持上一回的值,即使发生调用,也不会为该变量建立新的副本,即每次调用该函数时,不会重复初始化为0,会使用上一次保存的值,该变量会在各次调用之间共享。 

5-13 定义类X、Y、Z,函数h(X*),满足:类X有私有成员i,Y的成员函数g(X*)是X的友元函数,实现对X的成员i加1,类Z是类X的友元类,其成员函数f(X*)实现对X的成员i加5,函数h(X*)是X的友元函数,实现对X的成员i加10。在一个文件中定义和实现类,在另一个文件中实现main()函数。

//main文件
#include<iostream>
using namespace std;
 
#include"xyz.h"
int main()
{
    X d;
    d.show();
    
    Y d1;
    d1.g(&d);
    d.show();
 
    Z d2;
    d2.f(&d);
    d.show();
 
    h(&d);
    d.show();
    
    return 0;
}

//另外建一个名为xyz.h的头文件

#ifndef XYZ_H
#define XYZ_H

class X;
class Y
{
    public:
        void g(X* p);

};
class Z
{
    public:
        void f(X* p);

};

class X
{
    public:
        X():i(0){}
        friend void Y::g(X* p);
        friend class Z;
        friend void h(X* p);
        void show()
        {
            cout<<i<<endl;
        }
    private:
        int i;
};

void Y::g(X* p)
{
    p->i++;
}

void Z::f(X* p)
{
    p->i += 5;
}

void h(X* p)
{
    p->i += 10;
}

#endif // XYZ_H

代码解释:

  • 头文件“xyz.h”中 #ifndef  #define  #endif条件编译指令用途:防止头文件被多次定义,需用唯一的标识符来标记某文件是否已参加过编译保证头文件中定义的变量不存在重复声明或定义。标识符一般大写来防止与其他变量冲突,便于区分。
  • 友元关系提供了不同类或对象之间的数据共享机制,从字面意思也可以看出来,像“朋友”一样,开了一个绿色通道,让函数g(X*)、f(X*)、h(X*)能访问到类X的私有成员i。
  • 还需要注意的,友元函数并不属于这个类本身,故这个类本身的对象是无法访问到这些友元函数的。
  • 无论是友元函数还是友元类。都不能使用类内的this指针,同时也不可以被继承,如同父亲的朋友不一定是儿子的朋友这个道理。

5-14 定义Boat与Car两个类,二者都有weight属性,定义二者的一个友元函数totalWeight(),计算二者的重量和。

#include <iostream>
using namespace std;

class car;
class boat{
	private:
		int weight;
	public:
		boat(int w){weight = w;}
		friend int gettotalweight(boat &b, car &c);
};

class car{
	private:
		int weight;
	public:
		car(int w){weight = w;}
		friend int gettotalweight(boat &b, car &c);
};

int gettotalweight(boat &b, car &c){
	return b.weight+c.weight;
}
int main()
{
	boat b1(5);
	car c2(2);
	cout<<"Totalweight:"<<gettotalweight(b1,c2)<<endl;
	return 0;
}

PS:

  • 友元函数的形式:只需要在类内对这个函数进行声明,并在之前加上friend关键字。
  • 友元函数gettotalweight的形参boat &b,  car &c,这里&地址符的作用是引用的功能,通过地址改变对象的数据,传引用的好处是省去了复制,节约了空间和时间,提高了效率。
  • 另外,定义友元函数gettotalweight()时需要前向引用声明,声明另一个需要用到的类class car,使编译器知道还有这样一个类,才不会编译错误。

本专栏为本人大二C++课程的习题作业和一些学习经验的分享,供大家参考学习。如有侵权请立即与我联系,我将及时处理。


参考书籍为:C++语言程序设计 第五版 -清华大学出版社- 郑莉,董渊、C++语言程序设计 第五版 -清华大学出版社- 郑莉,董渊(学生用书)

编译环境:Visual Studio 2019、Dev-C++

欢迎关注我的微信公众号,分享一些有趣的知识:程序猿的茶水间

知秋君
上一篇 2024-07-24 07:36
下一篇 2024-07-24 07:02

相关推荐