C++学习刷题8--复制构造函数和赋值运算符重载函数

一、前言

本部分为C++语言刷题系列中的第8节,主要讲解这几个知识点:复制构造函数和赋值运算符重载函数。欢迎大家提出意见、指出错误或提供更好的题目!

二、知识点讲解

知识点1:复制构造函数

1、当依据一个已存对象创建一个新对象时,会自动调用复制构造函数,以便将旧对象的内容复制到新对象中进行初始化。例如,按值传递对象或按值返回对象。

2、如果类没有定义复制构造函数,则编译器会自动添加一个默认的复制构造函数。该默认复制构造函数将旧对象的内容完整复制给新对象,也称之为"浅复制"。

3、当类中存在指针型的成员变量时,应该提供一个自定义的复制构造函数,以实现依据内容的"深层复制"。

4、复制构造函数的形式:X(const X& x);

知识点2:赋值运算符重载函数

1、当将一个已存对象赋值给另一个已存对象时,会自动调用赋值运算符重载函数,以便将右值对象的内容复制到左值对象中。

2、如果类没有定义赋值运算符重载函数,则编译器会自动添加一个默认的赋值运算符重载函数。因此,赋值运算符重载函数只能以成员函数的方式实现,不能以友元函数的方式实现。同时,该默认赋值运算符重载函数将右值对象的内容完整复制给左值对象,也称之为"浅复制"。

3、当类中存在指针型的成员变量时,应该提供一个自定义的赋值运算符重载函数,以实现依据内容的"深层复制"。

4、赋值运算符重载函数的形式:X& operator=(const X& x);

三、试题解析

1.有如下类定义:

class Bag

{

public:

Bag(int p=200,char s='M') { price=p; size=s; cout<<size; }

private:

int price;

char size;

};

若执行语句

Bag Alice, Kelly(Alice), *Twins[2], F4[4];

则输出结果为( )。

A.MMMMMMMM

B.MMMMMM

C.MMMMM

D.MMMM

正确答案:C

解析:1、Bag Alice语句创建一个新对象,调用构造函数Bag(int p=200, char s='M'),输出M。2、Bag Kelly(Alice)语句由已存对象创建新对象,调用编译器生成的复制构造函数,没有输出内容。3、Bag *Twins[2]语句定义一个具有2个元素的指针数组,不涉及到对象的创建,不调用任何构造函数,也无任何输出。4、Bag F4[4]语句定义了具有4个Bag对象的数组,会调用构造函数Bag(int p=200, char s='M')四次,输出4个M。所以,输出结果为MMMMM。

2.有如下程序:

#include <iostream>

using namespace std;

class TV

{

public:

TV(int s=41):size(s) { }

TV(const TV &r):size(r.size) { }

~TV() { }

private:

int size;

};

TV fun(TV &u) { TV t=u; return t; }

void main() { TV x, y; x=fun(y); }

则 TV 类的复制构造函数被调用的次数是( )。

A.1次

B.2次

C.3次

D.4次

答案:B

解析:当依据一个已存对象创建一个新对象时,会调用复制构造函数。语句TV t=u;是由已存对象u创建新对象t,会调用一次复制构造函数。Return t;按值返回,也符合由已存对象创建一个新对象,会调用一次复制构造函数。因此,共调用2次复制构造函数,B选项正确。

3.为类MyClass重载赋值运算符时,应将其重载为类的( )。

A.静态函数

B.成员函数

C.友元函数

D.虚函数

正确答案:B

解析:如果类中没有定义赋值运算符重载函数,则编译器会自动提供一个默认的赋值运算符重载函数。因此,赋值运算符重载函数必须是类的成员函数,正确答案为B。

四、试题测试

1.下列情况中,不会调用复制构造函数的是( )。

A.用一个对象去初始化同一类的另一个新对象时

B.将类的一个对象赋值给该类的另一个对象时

C.函数的形参是类的对象,调用函数进行形参和实参结合时

D.函数的返回值是类的对象,函数执行返回调用时

2.有如下程序:

#include <iostream>

using namespace std;

class Test

{

public:

Test(int i=0) { cout<<'A'; }

Test(const Test &x) { cout<<''B; }

Test& operator =(const Test &x)

{

cout<<'C';

return *this;

}

~ Test() { cout<<'D'; }

};

void main()

{

Test obj1(1), obj2(obj1), obj3=obj1;

}

运行时的输出结果是( )。

A.AABDDD

B.AACADDDD

C.ABBDDD

D.ABCADDDD

3.下列关于赋值运算符=重载的叙述中,正确的是( )。

A.赋值运算符只能作为类的成员函数重载

B.默认的赋值运算符实现了"深层复制"功能

C.重载的赋值运算符函数有两个本类对象作为形参

D.如果已经定义了复制构造函数,就不能重载赋值运算符

4.有如下类定义:

class MyClass

{

public:

MyClass(const char *c=NULL);

~MyClass();

______________ //运算符=的声明

private:

char *p;

};

若要使语句序列

MyClass s1("test"), s2;

s2=s1;

能够正常运行,横线处的语句应为( )。

A. friend MyClass& operator=(const MyClass&);

B. MyClass& operator=(const MyClass&);

C. MyClass& operator=(MyClass,const MyClass&);

D. friend MyClass& operator=(MyClass,const MyClass&);

------------------------------

欢迎大家提出意见、指出错误或提供更好的题目,只有大家的共同努力,才能帮助更多人掌握C++的基本概念,顺利通过考试!

举报
评论 0