北京大学C++程序设计编程作业答案+解析·类和对象基础

本章一共包含四个编程习题:

  1. 奇怪的类复制
  2. 返回什么才好呢
  3. 超简单的复数类
  4. 哪来的输出

以下习题答案全部通过OJ,使用编译器为:G++(9.3(with c++17))

1. 奇怪的类复制

考点:构造函数、复制构造函数和类型转换构造函数

解析:首先我们先来分析需要几种构造函数:

// 类型转换构造函数
Sample a( 5 );
Sample c = 20;
// 复制构造函数
Sample b = a;
PrintAndDouble( b );
// 无参构造函数
Sample d;

从最简单的思路开始,我们先假定以下三个构造函数:

// 无参构造函数
Sample() {
    v = 0;
}
// 类型转换构造函数
Sample( int v ) {
    this->v = v;
}
// 复制构造函数
Sample( Sample &s ) {
    v = s.v;
}

无参构造只是初始化v = 0,类型转换和复制构造函数都只是简单复制原v的值,不做任何修改。接着,我们会在下面三处打印类成员变量的值,我们一个个分析,看看上面三个构造函数是否符合题意:

// 调用类型转换构造函数,所以a.v == 5
Sample a( 5 ); 
// 调用复制构造函数,所以b.v == 5
Sample b = a;
// 再次调用复制构造函数,所以函数内部o.v == 5
// 但是根据题意这里需要是9,比5大4,同时我们注意这之前我们调用了两次复制构造函数
// 所以我们有理由可以怀疑复制构造函数每次复制v之后,还需要+2
PrintAndDouble( b ); 
// 调用类型转换构造函数,所以c.v == 20
Sample c = 20;
// 调用复制构造函数,所以函数内部o.v == c.v + 2,符合题意的22
PrintAndDouble( c );
// 调用无参构造,所以d.v == 0
Sample d;
// 注意这里没有调用复制构造函数,因为这里不是初始化d,而是对d进行重新赋值
d = a;
// 所以d.v == a.v == 5,符合题意
std::cout << d.v;

答案:完整源码地址

// 这里只给到需要补完的代码,完整代码请移步到github
class Sample {
public:
    int v;
    // 在此处补充你的代码
    Sample() {
        v = 0;
    }

    Sample( int v ) {
        this->v = v;
    }
    
    Sample( Sample &s ) {
        v = s.v + 2;
    }
};

2. 返回什么才好呢

考点:this指针

解析:这里最主要的就是需要对类对象实例的函数返回值进行再次赋值,并且使用类型转换构造函数进行初始化对象,所以GetObj()返回值不能是指针,那么有两种选择,一个是对象本身,另一个是对象的引用,如果是对象本身,那么不会更改变量a所指向的对象,那么后面打印a.val的值都会是123,所以我们返回对象的引用。

答案:完整源码地址

// 这里只给到需要补完的代码,完整代码请移步到github
class A {
public:
    int val;

    // 在此处补充你的代码
    A( int v ) {
        val = v;
    }

    A () {
        val = 123;
    }

    A &GetObj() {
        return *this;
    }
};

3. 超简单的复数类

考点:类型转换函数

解析:这题就是使用类型转换函数对两个字符串进行转换,没有非常特别的难点。

答案:完整源码地址

// 这里只给到需要补完的代码,完整代码请移步到github
class Complex {
private:
    double r, i;
public:
    void Print() {
        std::cout << r << "+" << i << "i" << std::endl;
    }

    // 在此处补充你的代码
    Complex() {
        r = 0;
        i = 0;
    }

    Complex( const char *s ) {
        // std::string: char => string
        // std::stod: string => double
        r = std::stod( std::string( 1, s[ 0 ] ) );
        i = std::stod( std::string( 1, s[ 2 ] ) );
    }
};

4. 哪来的输出

考点:析构函数

解析:main函数里面没有任何打印语句,也没有调用有打印语句的函数,那么就只能析构函数中打印,因为这个函数会在对象被销毁时,自动被调用

答案:完整源码地址

// 这里只给到需要补完的代码,完整代码请移步到github
class A {
public:
    int i;

    A( int x ) { i = x; }

    // 在此处补充你的代码
    ~A() {
        std::cout << i << std::endl;
    }
};

上一章:

下一章:

5. 参考资料

  1. C++程序设计
  2. pixiv illustration: 佐倉おりこコラボカフェ開催!

6. 免责声明

※ 本文之中如有错误和不准确的地方,欢迎大家指正哒~

※ 此项目仅用于学习交流,请不要用于任何形式的商用用途,谢谢呢;


佐倉おりこコラボカフェ開催!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值