第三章 课后习题

一、填空题

1) 类定义中关键字private.public 和protected 以后的成员的访问权限分别是 私有  公有  保护 。如果没有使用关键字,则所有成员默认定义为 private 权限。具有 public 访问权限的数据成员才能被不属于该类的函数所直接访问。

2)定义成员函数时,运算符“::”是 作用域 运算符,“MyClass::"用于表明其后的成员函数是在“ MyClass类”中说明的。

3)在程序运行时,通过为对象分配内存来创建对象。在创建对象时,使用类作为 样板 ,故称对象为类的 实例 。

4)假定Dc是一个类,则执行“Dc a[10],b[2]”语句时、系统自动调用该类构造函数的次数为 11 

5)对于任意一个类,析构函数的个数最多为 1个 

6) delete 运算行通常用于实现释放该类对象中指针成员所指向的动态存储空间的和任务。

7)C++程序的内存格局通常分为4个区 数据区  代码区  栈区  堆区 

8)数据定义为全局变量,破坏了数据的 封装性 ,较好的解决办法是将所要共享的数据定义为类的静态成员

9)静态数据成员和静态成员函教可由 任意访问权限许可的函数访问。

10) 友元函数  友元类 统称为友元。

11)友元的正确使用能提高程序的 效率 ,但破坏了类的封装性和数据的隐蔽性。

12)若需要把一个类A定义为一个类B的友元类,则应在类B的定义中加入一条语句: friend class A

二、选择题(至少选一个,,可以多选)

1)以下不属于类存取权限的是(B)。

A.public B.static C.protected D. private

2)有关类的说法不正确的是(BC )。

A.类是一种用户自定义的数据类型

B.只有类的成员函数才能访向类的私有数据成员

C.在类中,如不做权限说明,所有的数据成员都是公有的

D.在类中,如不做权限说明,所有的数据成员都是私有的

3)在类定义的外部,可以被任意丽数访问的成员有(C)。

A.所有类成员

B.private 或protected 的类成员

C.public 的类成员

D.public 或private 的类成员

4)关于类和对象的说法( C )是错误的。

A 对象是类的一个实例

B,任何一个对象只能属于一个具体的类

C,一个类只能有一个对象

D. 类与对象的关系和数据类型与变量的关系相似

5) 设M Class 是一个类,dd是它的一个对象,PP是指向dd的指针,cc是dd的引用则对成员的访问,对象dd 可以通过( B )进行,指针PP 可以通过( D )进行,引用cc 可以通过( B )进行。

A.:: B. . C. & D. —>

6)关于成员函数的说法中不正确的是( C )

A.成员函数可以无返回值

B.成员函数可以重载

C.成员函数一定是内联函数

D.成员函数可以设定参数的默认值

7)下面对构造函数的不正确描述是( B )

A.系统可以提供默认的构造

B.构造函数可以有参数

C.构造函数可以重载

D.构造函数可以设置默认参数

8)假定A 是一个类,那么执行语句“A a ,b(3).*p;”调用了( B )次构造函数。

A.1 B. 2 C. 3 D.4

9)下面对析构函数的正确描述是 ( AC )

A 系统可以提供默认的析构函数

B. 析构函数必须由用户定义

C. 析构函数没有参数

D. 析构函数可以设置默认参数

10)类的析构函数是( D )时被调用的。

A. 类创创建 B. 创建对象 C. 引用对象 D.释放对象

11)建一个类的对象时,系统自动调用( B ),撤销对象时,系统自动调用( C )

A. 成员函数 B.构造函数 C.析构函数 D.拷贝构造函数

12) 通常拷贝构遗函数的参数是( C )
A.某个对象名

B. 某个对象的成员名

C. 某个对象的引用名

D.某个对象的指针名

13) 关于this指针的说法正确的是( B )。

A.this 指针必须显式说明

B.当创建一个对象后this指针就指向该对象

C.成员函数拥有this指针

D.静态成员函数拥有this指针

14)下列关于子对象的描述中,( B )是错误的。

A.子对象是类的一种数据成员,它是另一个类的对象

B.子对象可以是自身类的对象

C.对子对象的初始化要包含在该类的构造函数中

D.一个类中能含有多个子对象作其成员

15)对new运算符的下列描述中,( B )是错误的。

A.它可以动态创建对象和对象数组

B.用它创建对象数组时必须指定初始值

C.用它创建对象时要调用构造函数

D.用它创建的对象数组可以使用运算符delete 来一次释放

16) 对delete运算符的下列描述中,( D )是错误的。

A.用它可以释放用new运算符创建的对象和对象数组

B.用它即第一个对象时,它作用于一个new所返回的指针

C.用它释放一个对象教组时,它作用的指针名前须加下标运算符[]

D.用他可一次释放用new运算符创建的多个对象

17)关于静态数据成员,下面叙述不正确的是( C )

A 使用静态数据成员,实际是为了消除全局变量

B.可以使用“对象名,静态成员”或者“类名::静态成员”来访问静态数据成员

C.静态数据成员只能在静态成员函数中引用

D.所有对象的静态数据成员占用同一内存单元

18) 对静态数据成员的不正确描述是( CD )。

A.静态成员不属于对象,是类的共享成员

B.静态数据成员要在类外定义和初始化

C.调用静态成员函数时要通过类或对象激活,所以静态成员函数拥this指针

D.只有静态成员函数可以操作静态数据成员

19)下面的选项中,静态成员函数不能直接访问的是( D )。

A.静态数据成员 B,静态成员函数

C.类以外的函数和数据 D.非静态数据成员

20)在类的定义中,引人友元的原因是( A )。

A.提高效率 B.深化使用类的封装

C.提高程序的可能性 D.提高数据的隐秘性

21)友元类的声明方法有( A )

A.friend class<类名> B.youyuan class<类名>

C.class friend <类名> d.friends class<类名>

22)下面对友元的错误描述是( D )

A.关键字friend 用于声明友元

B.一个类中的成员函教可以是另一个类的友元

C.友元函数访问对象的成员不受访同特性影响

D.友元函数通过this 指针访问对象成员

23)下面选项中,( C )不是类的成员函数,

A.构造函数 B.析构函数 C.友元函数 D.拷贝构造函数

三、简答题

1) 类与对象有什么关系?

答:类是一种用户自己定义的数据类型,和其他数据类型不同的是,组成这种类型的不仅可以有数据,而且可以有对数据进行操作的函数。程序员可以使用这个新类型在程序中声明新的变量,具有类型的变量称为对象,创建对象时,类被用作样板,对象称为类的实例。

2) 类定义的-般形式是什么? 其成员有哪几种访问权限?

答:类定义的一般形式为: class类名

{

public:

<公有数据和函数>

protected:

<保护数据和函数>

private:

<私有数据和函数>

};

成员的访问权限: public、 protected和private的访问权限分别有公有、私有和保护。

3)类的实例化是指创建类的对象还是定义类?

答:指创建类的对象。

4)什么是this指针? 它的主要作用是什么?

答:this指针是C++语言为成员函数提供的一个隐含对象指针,它不能被显性声明。

作用:this指针是一个局部量,局部于某个对象。不同的对象调用同一个成员函数时,编译器根据this指针来确定应该引用哪一个对象的数据成员。

5)什么叫做拷贝构造函数? 拷贝构造函数何时被调用?

答:拷贝构造函数是一种特殊的构造函数,它的作用是用一个已经存在的对象去初始化另一个对象,为了保证所引用的对象不被修改,通常把引用声明为cons参数。

拷贝构造函数在以下3种情况下会被自动调用:

当用类的一个对象去初始化该类的另一个对象时。

当函数的形参是类的对象,进行形参实参的结合时。

当函数的返回值是类的对象,函数执行完成返回调用者时。

四、程序分析题

(1)

#include<iostream>  
using namespace std;  
class Test  
{  
private:  
    int num;  
public:  
    Test();  
    Test(int n);  
};  
Test::Test()  
{  
    cout<<"Init defa"<<endl;  
    num=0;  
}  
Test::Test(int n)  
{  
    cout<<"Init"<<""<<n<<endl;  
    num=0;  
}  
int main()  
{  
    Test x[2];  
    Test y(15);  
    return 0;  
}  

运行结果:


分析:程序声明了2个对象x和y,类中有两个构造函数。一个默认的构造函数Test(),一个带有参数的构造函数Test(int n),在执行Test x[2]时,创建对象x,调用默认构造函数,由于对象x是对象数组,每个数组元素被创建时都需要调用构造函数,所以默认构造函数被调用了两次,输出1、2行语句。接着执行Test y(15),创建对象y,调用带一个参数的构造函数,输出第三行结果。

(2)
#include<iostream>  

using namespace std;  
class Xx  
{  
private:  
 public:  
    Xx(int x)  
    {  
        num=x;  
    }  
    ~Xx()  
    {  
        cout<<"dst"<<num<<endl;  
    }  

};  

int main()  
{  
    Xx w(5);  
    cout<<"Exit main"<<endl;  
    return 0;  
}  

运行结果:   int num;  


分析:首先执行Xx w(5)创建对象w,调用构造函数,num得到初始值为5.接着执行cout<<"Exit main<<endl输出语句,输出第一行结果。当程序结束时,释放对象w,析构函数被调用,输出第二行结果。

(3)将例3.10中的Whole类如下修改,其他部分不变,写出输出结果。

class Whole
{
public:
Whole(int i); //Whole的有参构造函数
Whole(){}; //Whole的无参构造函数
~Whole(); //Whole的析构


Part p3; //子对象3
};
Whole::Whole(int i):p2(i),p1()
{
cout<<"Constructor of Whole"<<endl;
}
Whole::~Whole()
{
cout<<"Destructor of Whole"<<endl;

}函数
private:
Part p1; //子对象1
Part p2; //子对象2

修改后程序如下:

#include<iostream>  
using namespace std;  
class Part  
{  
    public:  
        Part();  
        Part(int x);  
       ~Part();  
   private:  
        int val;  
};  
Part::Part()  
{  
    val=0;  
    cout<<"Default constructor of Part"<<endl;  
}  
Part::Part(int x)  
{  
    val=x;  
    cout<<"Constructor of Part"<<","<<val<<endl;  
}  
Part::~Part()  
{  
    cout<<"Destructor of Part"<<","<<val<<endl;  
}  
class Whole  
{  
    public:  
        Whole(int i);  
        Whole(){};  
        ~Whole();  
    private:  
         Part p1;  
        Part p2;  
         Part p3;  
};  
Whole::Whole(int i):p2(i),p1()  
{  
    cout<<"Constructor of Whole"<<endl;  
}  
Whole::~Whole()  
{  
    cout<<"Destructor of Whole"<<endl;  
}  
int main()  
{  
   Whole w(3);  
    return 0;  
}
运行结果:

  

分析:程序Whole类中出现了类Part的3个对象p1、p2和p3作为该类的数据成员,则p1、p2和p3被称为子对象。当建立的Whole类的对象w时,子对象p1、p2和p3被建立,所指定的构造函数被执行。由于p1在Whole类中先说明,所以先执行它所使用的构造函数,即类Part的默认构造函数。接着p2执行它所使用的有参构造函数,最后初始化p3,由于Whole类构造函数的成员初始化列表中没有子对象p3进行初始化的选项,所以执行类Part的默认构造函数,当所有子对象被构造完成之后,对象w的构造函数才被执行,从而得到前4行输出结果。后4行是执行相应析构函数的输出结果。

(4)

#include<iostream>  
using namespace std;  
class Book  
{  
    public:  
       Book(int w);  
       static int sumnum;  
    private:  
        int num;  
};  
Book::Book(int w)  
{  
    num=w;  
    sumnum-=w;  
}  
int Book::sumnum=120;  
int main()  
{  
    Book b1(20);  
    Book b2(70);  
    cout<<Book::sumnum<<endl;  
    return 0;  
}  

运行结果:


分析:intBook::sumnum=120”这条语句是给sumnum初始化并给sumnum赋值120,“Book b1(20)”调用构造函数,这时sumnum的值变为100,接着又调用构造函数,sumnum的值就变成了30。

五、程序设计题
(1)声明一个Cricle类,有数据成员radius(半径)、成员函数area(),计算圆的面积,构造一个Cricle的对象进行测试。
编写的程序如下:

#include<iostream>  
using namespace std;  
const float PI=3.14;  
class Circle  
{      public:  
        Circle(float r)  
        {  
            radius=r;  
        }  
         float area()  
        {  
            return radius*radius*PI;  
        }  
    private:  
    float radius;  
};  
int main()  
{  
    Circle c(6);  
    cout<<"圆的面积="<<c.area()<<endl;  
}  
运行结果:

(2)重新编写程序分析题(4)的程序,设计一个静态成员函数,用来输出程序分析题(4)中的静态数据成员的值。

编写的程序如下:

#include<iostream>  
using namespace std;  
class Book  
{  
    public:  
       Book(int w);  
       static int sumnum;  
       static int getsum()  
       {  
           return sumnum;  
       }  
    private:  
        int num;  
};  
Book::Book(int w)  
{  
    num=w;  
    sumnum-=w;  
}  
int Book::sumnum=120;  
int main()  
{  
    Book b1(20);  
    Book b2(70);  
    cout<<Book::getsum()<<endl;  
    return 0;  
}  

运行结果:

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页