#include <iostream> #include <string> #include <vector> #include <array> template <typename T> void output1(const T &obj) { for (auto i : obj) std::cout << i << ","; std::cout << "\b \n"; } template <typename T> void output2(const T &obj) { for (auto p = obj.begin(); p != obj.end(); ++p) std::cout << *p << ","; std::cout << "\b \n"; } void test_array() { using namespace std; array<int, 5> x1; cout << "x1.size()=" << x1.size() << endl; x1.fill(42); x1.at(0) = 999; x1[4] = -999; cout << "x1:"; output1(x1); cout << "x1:"; output2(x1); array<int, 5> x2(x1); cout << boolalpha << (x1 == x2) << endl; x2.fill(22); cout << "x2:"; output1(x2); swap(x1, x2); cout << "x1:"; output1(x1); cout << "x2:"; output1(x2); } void test_vector() { using namespace std; vector<int> v1; cout << v1.size() << endl; cout << v1.max_size() << endl; v1.push_back(55); cout << "v1:"; output1(v1); vector<int> v2{1, 0, 5, 2}; v2.pop_back(); v2.erase(v2.begin()); v2.insert(v2.begin(), 999); v2.insert(v2.end(), -999); cout << v2.size() << endl; cout << "v2:"; output2(v2); vector<int> v3(5, 42); cout << "v3"; output1(v3); vector<int> v4(v3.begin(), v3.end()-2); cout << "v4:"; output1(v4); } void test_string() { using namespace std; string s1{"opp"}; cout << s1.size() << endl; for (auto &i : s1) i -= 32; s1 += "2023"; s1.append(",hello"); cout << s1 << endl; } int main() { using namespace std; cout << "=======测试1:array模板类基础用法======\n"; test_array(); cout << "\n=======测试2:vector====\n"; test_vector(); cout << "\n=======测试3:string====\n"; test_string(); return 0; }
1 #include <iostream> 2 #include <complex> 3 4 // 测试标准库提供的复数类模板complex 5 void test_std_complex() { 6 using namespace std; 7 complex<double> c1{3, 4}, c2{4.5}; 8 const complex<double> c3{c2}; 9 cout << "c1 = " << c1 << endl; 10 cout << "c2 = " << c2 << endl; 11 cout << "c3 = " << c3 << endl; 12 cout << "c3.real = " << c3.real() << ", " << "c3.imag = " << c3.imag() 13 << endl; 14 cout << "c1 + c2 = " << c1 + c2 << endl; 15 cout << "c1 - c2 = " << c1 - c2 << endl; 16 cout << "abs(c1) = " << abs(c1) << endl; // abs()是标准库数学函数,对复数取模 17 cout << boolalpha; // 设置bool型值以true/false方式输出 18 cout << "c1 == c2: " << (c1 == c2) << endl; 19 cout << "c3 == c2: " << (c3 == c2) << endl; 20 complex<double> c4 = 2; 21 cout << "c4 = " << c4 << endl; 22 c4 += c1; 23 cout << "c4 = " << c4 << endl; 24 } 25 26 int main() { 27 test_std_complex(); 28 }
1 // 一个简单的类T:定义、使用 2 #include <iostream> 3 #include <string> 4 using namespace std; 5 // 类T的声明 6 class T { 7 public: 8 T(int x = 0, int y = 0); // 带有默认形值的构造函数 9 T(const T &t); // 复制构造函数 10 T(T &&t); // 移动构造函数 11 ~T(); // 析构函数 12 void set_m1(int x); // 设置T类对象的数据成员m1 13 int get_m1() const; // 获取T类对象的数据成员m1 14 int get_m2() const; // 获取T类对象的数据成员m2 15 void display() const; // 显示T类对象的信息 16 friend void func(); // 声明func()为T类友元函数 17 private: 18 int m1, m2; 19 public: 20 static void disply_count(); // 类方法,显示当前T类对象数目 21 public: 22 static const string doc; // 类属性,用于描述T类 23 static const int max_count; // 类属性,用于描述T类对象的上限 24 private: 25 static int count; // 类属性,用于描述当前T类对象数目 26 }; 27 // 类的static数据成员:类外初始化 28 const string T::doc{"a simple class"}; 29 const int T::max_count = 99; 30 int T::count = 0; 31 // 类T的实现 32 T::T(int x, int y): m1{x}, m2{y} { 33 ++count; 34 cout << "constructor called.\n"; 35 } 36 T::T(const T &t): m1{t.m1}, m2{t.m2} { 37 ++count; 38 cout << "copy constructor called.\n"; 39 } 40 T::T(T &&t): m1{t.m1}, m2{t.m2} { 41 ++count; 42 cout << "move constructor called.\n"; 43 } 44 T::~T() { 45 --count; 46 cout << "destructor called.\n"; 47 } 48 void T::set_m1(int x) { 49 m1 = x; 50 } 51 int T::get_m1() const { 52 return m1; 53 } 54 int T::get_m2() const { 55 return m2; 56 } 57 void T::display() const { 58 cout << m1 << ", " << m2 << endl; 59 } 60 // 类方法 61 void T::disply_count() { 62 cout << "T objects: " << count << endl; 63 } 64 // 友元函数func():实现 65 void func() { 66 T t1; 67 t1.set_m1(55); 68 t1.m2 = 77; // 虽然m2是私有成员,依然可以直接访问 69 t1.display(); 70 } 71 // 测试 72 void test() { 73 cout << "T class info: " << T::doc << endl; 74 cout << "T objects max_count: " << T::max_count << endl; 75 T::disply_count(); 76 T t1; 77 t1.display(); 78 t1.set_m1(42); 79 T t2{t1}; 80 t2.display(); 81 T t3{std::move(t1)}; 82 t3.display(); 83 t1.display(); 84 T::disply_count(); 85 } 86 // 主函数 87 int main() { 88 cout << "============测试类T============" << endl; 89 test(); 90 cout << endl; 91 cout << "============测试友元函数func()============" << endl; 92 func(); 93 }
#include <iostream> #include <string> #include <iomanip> using namespace std; class Rect { private: static const string doc; static int size; double length; double width; public: Rect() : length(2.0), width(1.0) { size++; } Rect(double l, double w) : length(l), width(w) { size++; } Rect(const Rect& r) : length(r.length), width(r.width) { size++; } ~Rect() { size--; } static int size_info() { return size; } double len() { return length; } double wide() { return width; } double area() { return length * width; } double circumference() { return 2 * (length + width); } void resize(double times) { length *= times; width *= times; } void resize(double l_times, double w_times) { length *= l_times; width *= w_times; } void output() { cout << "矩形信息: " << endl; cout << fixed << setprecision(2); cout << "长度: " << length << endl; cout << "宽度: " << width << endl; cout << "面积: " << area() << endl; cout << "周长: " << circumference() << endl; } }; const string Rect::doc = "Rect类用于表示矩形"; int Rect::size = 0; void output(const Rect &r) { r.output(); } void test() { cout << "矩形类信息: " << Rect::doc << endl; cout << "当前矩形对象数目: " << Rect::size_info() << endl; Rect r1; output(r1); Rect r2(4, 3); output(r2); Rect r3(r2); r3.resize(2); output(r3); r3.resize(5, 2); output(r3); cout << "当前矩形对象数目: " << Rect::size_info() << endl; } int main() { test(); cout << "当前矩形对象数目: " << Rect::size_info() << endl; }
#include <iostream> #include <cmath> class Complex { private: double real; // 实部 double imag; // 虚部 public: // 构造函数 Complex() : real(0), imag(0) {} // 不带参数,相当于0 + 0i Complex(double r) : real(r), imag(0) {} // 只有一个参数,相当于r + 0i Complex(double r, double i) : real(r), imag(i) {} // 两个参数,相当于r + i // 成员函数 double get_real() const { return real; } // 返回实部 double get_imag() const { return imag; } // 返回虚部 void show() const { // 输出复数 std::cout << real << (imag >= 0 ? "+" : "-") << std::abs(imag) << "i"; } void add(const Complex& c) { // 将一个复数加到自身 real += c.real; imag += c.imag; } // 友元函数 friend Complex add(const Complex& c1, const Complex& c2); // 实现两个复数相加 friend bool is_equal(const Complex& c1, const Complex& c2); // 判断两个复数是否相等 friend double abs(const Complex& c); // 对复数进行取模运算 }; Complex add(const Complex& c1, const Complex& c2) { Complex result(c1.real + c2.real, c1.imag + c2.imag); return result; } bool is_equal(const Complex& c1, const Complex& c2) { return (c1.real == c2.real) && (c1.imag == c2.imag); } double abs(const Complex& c) { return std::sqrt(c.real * c.real + c.imag * c.imag); } // 复数类Complex: 测试 void test() { using namespace std; Complex c1(3, -4); const Complex c2(4.5); Complex c3(c1); cout << "c1 = "; c1.show(); cout << endl; cout << "c2 = "; c2.show(); cout << endl; cout << "c2.imag = " << c2.get_imag() << endl; cout << "c3 = "; c3.show(); cout << endl; cout << "abs(c1) = " << abs(c1) << endl; cout << boolalpha; cout << "c1 == c3: " << is_equal(c1, c3) << endl; cout << "c1 == c2: " << is_equal(c1, c2) << endl; Complex c4; c4 = add(c1, c2); cout << "c4 = c1 + c2 = "; c4.show(); cout << endl; c1.add(c2); cout << "c1 += c2, c1 = "; c1.show(); cout << endl; } int main() { test(); return 0; }
通过本次实验,我收获了以下具体知识点和思考:
1. 类的抽象是指将具有相似属性和行为的对象归纳到一个类中,通过提取共性特征来创建类,从而实现对多个对象进行统一管理和操作。封装是指将数据和函数封装在类的内部,对外部隐藏实现细节,通过公共接口进行访问和操作。
2. 使用C++语法规则可以通过class关键字正确定义类。在类内部声明数据成员和成员函数,并在类外部定义成员函数的实现。通过创建对象并调用其成员函数来测试类的正确性。
3. 在C++中,使用new关键字可以正确创建对象,通过对象名和点操作符可以访问对象的成员。基于对象编程是以对象为中心,通过对象之间的交互完成任务,能够更好地组织和管理复杂系统。
4. 构造函数用于初始化对象的数据成员,析构函数用于释放对象占用的资源。构造函数在创建对象时自动调用,析构函数在对象生命周期结束时自动调用。构造函数和析构函数的调用时机取决于对象的创建和销毁。
5. 在设计和实践类时,合理利用访问权限控制、static成员、友元机制和const修饰符可以在数据共享和保护之间达到平衡。访问权限控制可以限制成员的可访问性,static成员可以在类的所有对象之间共享,友元机制可以访问另一个类的私有成员,const修饰符可以声明常量成员函数和数据成员。
6. 通过实践,我体会到了面向对象方法与结构化方法在编程解决实际问题时思维方式的不同。面向对象方法注重对象之间的交互和关系,通过封装、继承和多态等特性来解决问题;而结构化方法注重程序的结构和流程,通过模块化和顺序、选择、循环等结构来解决问题。面向对象方法能够更好地组织和管理复杂系统,提高代码的可重用性和可维护性。
通过以上梳理和总结,我对OOP中类、对象的概念有了更深入的理解,能够正确定义、实现、测试类,并能够正确创建对象并基于对象进行编程。我对C++内存资源管理技术有了更深入的了解,能够解释构造函数、析构函数的用途,并能分析它们何时会被调用。我也学会在设计和实践类时合理利用访问权限控制、static成员、友元机制、const修饰符,在数据共享和保护之间达到平衡。最重要的是,我通过实践深刻体会到了面向对象方法与结构化方法在编程解决实际问题时思维方式的不同。