实验1 类和对象(1)

实验目的

  1. 通过实践,加深对类、对象的理解,能够解释类的抽象、封装所指,能够描述什么是类的接口
  2. 能够使用C++语法规则正确定义、实现、测试类
  3. 能够使用C++语法规则正确创建对象,并基于对象编程
  4. 通过实践,加深对C++内存资源管理技术的理解,能否解释构造函数、析构函数的用途,并能够分
    析它们何时会被调用
  5. 通过实践,体会和理解面向对象方法与结构化方法在编程解决实际问题时思维方式的不同

实验任务2

程序源码

#include <iostream>
using std::cout;
using std::endl;
// 定义Point类
class Point
{
public:
    Point(int x0 = 0, int y0 = 0);
    Point(const Point &p);
    ~Point() = default;
    int get_x() const { return x; }
    int get_y() const { return y; }
    void show() const;
private:
    int x, y;
};
// Point类的实现
// 构造函数(带有默认形参值)
Point::Point(int x0, int y0) : x{x0}, y{y0}
{
    cout << "constructor called." << endl;
}
// 复制构造函数
// 参数必须是自身对象的引用类型
Point::Point(const Point &p) : x{p.x}, y{p.y}
{
    cout << "copy constructor called." << endl;
}
void Point::show() const
{
    cout << "(" << x << ", " << y << ")" << endl;
}
int main(int argc, char const *argv[])
{
    Point p1(4,5);    //构造函数被调用
    p1.show();
    Point p2 = p1;    //复制构造函数被调用
    p2.show();
    Point p3{p2};     //复制构造函数被调用
    p3.show();
    cout << p3.get_x() << endl;
    return 0;
}

测试截图

测试1

实验任务3

程序源码

#include <iostream>
#include <iomanip>
using std::cout;
using std::endl;
// 定义时钟类Clock
class Clock
{
public:
    Clock(int h = 0, int m = 0, int s = 0);
    Clock(const Clock &t);
    ~Clock() = default;
    void set_time(int h, int m = 0, int s = 0);
    void show_time() const;

private:
    int hour, minute, second;
};
// 类Clock实现
Clock::Clock(int h, int m, int s) : hour{h}, minute{m}, second{s}
{
    cout << "constructor called" << endl;
}
Clock::Clock(const Clock &t) : hour{t.hour}, minute{t.minute}, second{t.second}
{
    cout << "copy constructor called" << endl;
}
void Clock::set_time(int h, int m, int s)
{
    hour = h;
    minute = m;
    second = s;
}
void Clock::show_time() const
{
    using std::setfill;
    using std::setw;
    cout << setfill('0') << setw(2) << hour << ":"
         << setw(2) << minute << ":" << setw(2) << second << endl;
}
// 普通函数定义
Clock reset()
{
    return Clock(0, 0, 0); //构造函数被调用
}
int main(int argc, char const *argv[])
{
    Clock c1(6, 6, 6); // 构造函数被调用
    c1.show_time();
    c1 = reset(); // 理论上:复制构造函数被调用
    c1.show_time();
    Clock c2(c1); // 复制构造函数被调用
    c2.set_time(6);
    c2.show_time();
    return 0;
}

测试截图

测试2

实践任务4

程序源码

#include <iostream>
// 定义一个简单类
class X
{
public:
    X();             //默认构造函数
    ~X();            //析构函数
    X(int m);        //构造函数
    X(const X &obj); // 复制构造函数
    X(X &&obj)
    noexcept; //移动构造函数
    void show() const;

private:
    int data;
};
X::X() : data{42}
{
    std::cout << "default constructor called.\n";
}
X::~X()
{
    std::cout << "destructor called.\n";
}
X::X(int m) : data{m}
{
    std::cout << "constructor called.\n";
}
X::X(const X &obj) : data{obj.data}
{
    std::cout << "copy constructor called.\n";
}
X::X(X &&obj) noexcept : data{obj.data}
{
    std::cout << "move constructor called.\n";
}
void X::show() const
{
    std::cout << data << std::endl;
}
int main(int argc, char const *argv[])
{
    X x1; //默认构造函数被编译器自动调用
    x1.show();
    X x2{2049};
    x2.show(); // 构造函数被编译器自动调用
    X x3{x1};  // 复制构造函数被编译器自动调用
    x3.show();
    X x4{std::move(x2)};// 移动构造函数被编译器调用
    x4.show();
    return 0;
}

测试截图

测试3

实验分析

X x1;

默认构造函数被调用

X x2{2049};

定义的构造函数被调用

X x3{x1};

复制构造函数被调用

X x4{std::move(x2)};

移动构造函数被调用
析构函数在return 0;前调用,顺序是x4,x3,x2,x1

实验任务5

程序源码

#include <iostream>
#include <iomanip>
// 矩形类Rectangle的定义和实现
class Rectangle
{
private:
    double length, width;

public:
    Rectangle();
    Rectangle(double l, double w);
    Rectangle(const Rectangle &copy);
    ~Rectangle() = default;
    double len() const;
    double wide() const;
    double area() const;
    double circumference() const;
    void resize(int times);
    void resize(int l_times, int w_times);
};

Rectangle::Rectangle() : length{2.00}, width{1.00} {}
Rectangle::Rectangle(double l, double w) : length{l}, width{w} {}
Rectangle::Rectangle(const Rectangle &copy) : length{copy.length}, width{copy.width} {}
double Rectangle::len() const { return length; }
double Rectangle::wide() const { return width; }
double Rectangle::area() const { return length * width; };
double Rectangle::circumference() const { return 2 * (length + width); };
void Rectangle::resize(int times)
{
    length *= times;
    width *= times;
};
void Rectangle::resize(int l_times, int w_times)
{
    length *= l_times;
    width *= w_times;
};

// 普通函数, 用于输出矩形信息
void output(const Rectangle &rect)
{
    using namespace std;
    cout << "矩阵信息:" << endl;
    cout << fixed << setprecision(2); // 控制输出格式:以浮点数形式输出、小数部分保留两位
    // 分行输出矩形长、宽、面积、周长
    cout <<setfill(' ')<< setw(8) <<left<< "长:" << rect.len() << endl
         <<setfill(' ')<< setw(8) <<left<< "宽:" << rect.wide() << endl
         <<setfill(' ')<< setw(8) <<left<< "面积:" << rect.area() << endl
         <<setfill(' ')<< setw(8) <<left<< "周长:" << rect.circumference() << endl;
}
// 主函数,测试Rectangle类
int main()
{
    Rectangle rect1; // 默认构造函数被调用
    output(rect1);
    Rectangle rect2(10, 5); // 带有两个参数的构造函数被调用
    output(rect2);
    Rectangle rect3(rect1); // 复制构造函数被调用
    rect3.resize(2);        // 矩形rect3的长和宽同时缩放2倍
    output(rect3);
    rect3.resize(5, 2); // 矩形rect3的长缩放5倍, 宽缩放2倍
    output(rect3);
    return 0;
}

测试截图

测试4

实验总结

通过这次实验,我学会了:

  1. 类、对象的基础理解,知道了什么是类的抽象、封装,类的接口
  2. 用C++正确定义、实现、测试类
  3. 用C++正确创建对象,并基于对象编程
  4. 对C++内存资源管理技术的初步了解,知道构造函数、析构函数的用途和调用时机
posted @ 2022-09-28 16:45  水孔蛋白  阅读(112)  评论(0编辑  收藏  举报