第五章 堆与复制构造函数

选择题

(部分)
3.下列函数中,( )不能重载。(C)
A.成员函数
B.非成员函数
C.析构函数
D.构造函数

8.下列关于类的构造函数的描述中,错误的是(D)
A.类的构造函数可以重载
B.类可以没有构造函数
C.类的构造函数可以缺省
D.类的构造函数可以作为其它类型向本类类型进行转换的函数

1.设A为自定义类,现有普通函数int fun(A& x)。则在该函数被调用时:(C)
//***
A.将执行复制构造函数来初始化形参x
B.仅在实参为常量时,才会执行复制构造函数以初始化形参x
C.无需初始化形参x
D.仅在该函数为A类的友元函数时,无需初始化形参x

2.在以下哪种情形,复制构造函数会被调用。(B)//
A.当一个对象采用引用方式,作为参数传递给一个函数
B.当一个函数采用值方式,返回一个对象
C.当一个对象赋值给另一个对象
D.以上答案都不对

3.假设A是一个类的名字,下面哪段程序不会用到A的拷贝构造函数?(D)

A.A a1,a2; a1=a2;
B.void func( A a) { cout<<“good”<< endl; }
C.A func() { A tmp; return tmp;}
D.A a1; A a2(a1);

判断题

1.将构造函数说明为纯虚函数是没有意义的。(T)
2.对象间赋值将调用拷贝构造函数。(F)

编程题

1.实现数组类(C++ 拷贝构造函数、拷贝函数)
裁判测试程序样例中展示的是一段实现“数组类”的代码,其中缺失了部分代码,请补充完整,以保证测试程序正常运行。
函数接口定义:

提示:要想程序正确运行,至少需要补充以下函数(可能还需要补充其他函数):
1. 带参构造函数
2. 拷贝构造函数
3. 拷贝函数(赋值运算符重载)

裁判测试程序样例:

#include <iostream>
using namespace std;
class ArrayIndexOutOfBoundsException{  // 异常类
public:
    int index;
    ArrayIndexOutOfBoundsException(int k){
        index = k;
    }
};
class Array{
private:
    int *data;
    int size;
    static const int dSize = 10;   // 数组默认大小
public:
    Array( ){  // 无参构造
        size = dSize;
        data = new int[size]( );
    }

/** 你提交的代码将被嵌在这里(替换本行内容) **/        

    int& operator [] (int k){     // 运算符 [ ] 重载,以方便数组的使用
        if(k<0 || k>=size) throw ArrayIndexOutOfBoundsException(k);
        return data[k];
    }
    friend ostream& operator << (ostream& o, const Array& a);   // 运算符 << 重载,以方便输出
};
ostream& operator << (ostream& o, const Array& a){
    o << '[' ;
    for(int i=0; i<a.size-1; i++)
        o << a.data[i] << ',' ;
    o << a.data[a.size-1] << ']';
    return o;
}
// 注意:实际测试程序中,在此处之前的代码与样例中相同
// 注意:实际测试程序中,在此处之后的代码(即main函数)可能与样例中不同
int main(){
    int n, k;
    cin >> n >> k;
    Array a(n);  // 构造数组,大小为 n
    for(int i=0; i<n; i++) a[i] = i;
    Array b = a;  // 拷贝构造数组
    b[n/2] = k;
    cout << a << endl;
    cout << b << endl;
    Array c;  // 构造数组,默认大小
    c = a; // 拷贝数组
    c[n/2] = k;
    cout << a << endl;
    cout << c << endl;
    a = a;
    a[n/2] = 2223;
    cout << a << endl;
    return 0;
}

输入样例:

15 666

输出样例:

[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]
[0,1,2,3,4,5,6,666,8,9,10,11,12,13,14]
[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]
[0,1,2,3,4,5,6,666,8,9,10,11,12,13,14]
[0,1,2,3,4,5,6,2223,8,9,10,11,12,13,14]

1.学生成绩的快速录入
现在需要录入一批学生的成绩(学号,成绩)。其中学号是正整数,并且录入时,后录入学生的学号会比前面的学号大;成绩分两等,通过(Pass,录入时用1代表),不通过(Fail,录入时用0代表)。

由于很多学号都是相邻的,并且学号相邻的学生成绩常常相同。所以在录入时,适当地加了速。如果当前学生的学号比前面的学号大1,且成绩与前面的成绩相同,则只输入0即可。

类定义:完成Student类

裁判测试程序样例:

#include<iostream>
using namespace std;

/* 请在这里填写答案 */

int main(){
    const int size=100;
    int i, N, no, score;
    Student *st[size];
    cin>>N;
    for(i=0; i<N; i++){
        cin>>no;
        if(no>0){
            cin>>score;
            st[i]=new Student(no, score);
        }
        else
            st[i]=new Student(*st[i-1]);
    }
    cout<<Student::count<<" Students"<<endl;
    for(i=0;i<N;i++) st[i]->display();
    for(i=0;i<N;i++) delete st[i];
    return 0;
}

输入样例:

5
3 0
0
7 1
0
12 1

输出样例:

5 Students
3 Fail
4 Fail
7 Pass
8 Pass
12 Pass
class Student{
private:
	int num,s;
public:
	static int count;
	Student(int n,int s1)
	{
		num = n;
		s = s1;
		count++;
	}
	Student(const Student &obj)
	{
		num =obj.num+1;
		s=obj.s;
		count++;
	}
	void display()
	{
		if(s==1)
			cout<<num<<" Pass\n";
		else cout<<num<<" Fail\n";
	}

};
int Student::count = 0;

2.解决内存泄漏问题
编译、运行下列程序后。从输出结果发现没有调用 class Y 的析构函数,出现了内存泄漏。请尝试修改class X类的定义解决这个内存泄露问题。并提交定义class X类的代码。
class X类的定义如下:

class X{
public:
    X() { p = new int[2]; cout << "X().    "; }
   ~X() { delete [] p; cout << "~X().\n"; }
private:
    int* p;
};
#include <iostream> 
using namespace std; 
// 你提交的代码将嵌入到这里


class Y : public X
{
public:
   Y( ) { q = new int[1023]; cout << "Y( )    "; }
   ~Y( ) { delete [] q; cout << "~Y().    "; }
private:
   int* q;
};
int main()
{
  int n;
  cin>>n; 
  for (int i = 0; i < n; i++)
  {
    X* r = new Y;
    delete r;
  }
  return 0;
}
从输出结果发现没有调用 class Y 的析构函数,出现了内存泄漏。
3
X().    Y( )    ~X().
X().    Y( )    ~X().
X().    Y( )    ~X().

输入样例:

3

输出样例:(输出显示调用了Y类的析构函数)

X().    Y( )    ~Y().    ~X().
X().    Y( )    ~Y().    ~X().
X().    Y( )    ~Y().    ~X().
1.
// 这个测试样例不知道能过不
class X{
public:
    X() { p = new int[2]; cout << "X().    "; }
   ~X() { delete [] p; cout << "~Y().    ~X().\n"; }
private:
    int* p;
};
2.
class X{
public:
    X() { p = new int[2]; cout << "X().    "; }
 virtual  ~X() { delete [] p; cout << "~X().\n"; }
private:
    int* p;
};

3.为my_string类创建复制构造函数copy constructor
为下面的my_string类创建一个复制构造函数,并将定义该类的代码提交。

my_string类的定义:

class my_string {
   char *s;
public:
   my_string(char *str)  {
      s = new char[strlen(str)+1];
      strcpy(s, str);
   }
   ~my_string() {
       if(s) delete [] s;
       cout << "Freeing s\n"; 
    }
   void show() { cout << s << "\n"; }
};

裁判测试程序样例:

#include <iostream>
#include <cstring>
using namespace std;
// 你提交的代码将被嵌入到这里


int main()
{
   char str[80];
   cin>>str;
   my_string obj(str); 

   my_string ob1(obj);    
   my_string ob2=ob1;

   ob1.show();
   ob2.show();

   return 0;
}

输入样例:

ByeBye

输出样例:

ByeBye
ByeBye
Freeing s
Freeing s
Freeing s

class my_string {
   char *s;
public:
   my_string(char *str)  {
      s = new char[strlen(str)+1];
      strcpy(s, str);
   }
   my_string(const my_string &o)
   {
		s = new char[strlen(o.s)+1];
        strcpy(s,o.s);
   }
   ~my_string() {
       if(s) delete [] s;
       cout << "Freeing s\n"; 
    }
   void show() { cout << s << "\n"; }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值