diff --git a/README.md b/README.md index 12b8932..b3ff383 100644 --- a/README.md +++ b/README.md @@ -7,3 +7,5 @@ #### day2: const 和#define 的区别, 引用(reference) 【重要】, 内联函数, 函数的默认值参数, 函数的占位参数, 函数重载和 extern "c", 类与对象的概念, 面向对象程序设计案例 #### day3: 对象的构造与析构, 构造函数的分类与调用, 拷贝构造函数的调用时机, 构造函数的调用规则, 深拷贝和浅拷贝, 多个对象的构造和析构(初始化列表, 类对象作为成员), explicit 关键字(禁止隐式转换), 动态创建对象(malloc/realloc/calloc 在堆中创建空间, new 关键字), 扩展 new 和 delete, + +#### day4: static 静态成员, 类的单例设计模式, 对象的存储(this 指针与链式编程, const 修饰成员函数与类对象), 友元, 运算符重载 diff --git a/day4/d1.cpp b/day4/d1.cpp new file mode 100644 index 0000000..ae4af56 --- /dev/null +++ b/day4/d1.cpp @@ -0,0 +1,26 @@ +// 类的静态成员变量的声明、初始化与访问 +#include +#include +#include + +using namespace std; + +class A +{ +public: + static int x; +}; + +int A::x = 20; // 静态变量初始化,静态成员变量初始化时不需要 static + +int main() +{ + A a1, a2; + // 访问类的静态成员: 1) A::x, 2) 对象名.x + cout << "A::x = " << A::x << endl; // 20 + A::x = 30; + cout << "a1.x = " << a1.x << endl; // 30 + cout << "a2.x = " << a2.x << endl; // 30 + + return 0; +} \ No newline at end of file diff --git a/day4/d10.cpp b/day4/d10.cpp new file mode 100644 index 0000000..2bf769e --- /dev/null +++ b/day4/d10.cpp @@ -0,0 +1,32 @@ +// 重载 C++ 的 << 输出流运算符 +#include +#include +#include + +using namespace std; + +class A +{ + friend ostream &operator<<(ostream &cout, A &a); + +private: + int x, y; + +public: + A(int x, int y) : x(x), y(y) {} +}; + +// << 输出运算符重载 +ostream &operator<<(ostream &cout, A &a) +{ + // x, y 是 A 类的私有成员 + cout << "a.x : " << a.x << ", a.y : " << a.y << endl; + return cout; +} + +int main() +{ + A a1(1, 2); + cout << a1; + return 0; +} diff --git a/day4/d11.cpp b/day4/d11.cpp new file mode 100644 index 0000000..5c902b0 --- /dev/null +++ b/day4/d11.cpp @@ -0,0 +1,39 @@ +// 重载 C++ 的 >> 输入流运算符 +#include +#include +#include + +using namespace std; + +class Worker +{ + friend istream &operator>>(istream &cin, Worker &obj); + friend ostream &operator<<(ostream &cout, Worker &obj); + +private: + string name; + int salary; +}; + +istream &operator>>(istream &cin, Worker &obj) +{ + cout << "Name: "; + cin >> obj.name; + cout << "salary: "; + cin >> obj.salary; + return cin; +} + +ostream &operator<<(ostream &cout, Worker &obj) +{ + cout << "Worker name is " << obj.name << ", salary is " << obj.salary << endl; + return cout; +} + +int main() +{ + Worker w1; + cin >> w1; + cout << w1; + return 0; +} \ No newline at end of file diff --git a/day4/d12.cpp b/day4/d12.cpp new file mode 100644 index 0000000..6829cc8 --- /dev/null +++ b/day4/d12.cpp @@ -0,0 +1,52 @@ +// 重载运算符 +#include +#include +#include + +using namespace std; + +class Num +{ +private: + int n; + +public: + explicit Num(int n) : n(n) + { + } + bool operator>(int other) + { + return this->n > other; + } + bool operator<(int other) + { + return this->n < other; + } + bool operator>(Num &other) + { + return this->n > other.n; + } + bool operator<(Num &other) + { + return this->n < other.n; + } +}; + +int main(int argc, char const *argv[]) +{ + Num n1(atoi(argv[1])), n2(atoi(argv[2])); + if (n1 > 20) + { + cout << "n1 大于 20" << endl; + + if (n1 < n2) + { + cout << "n1 小于 n2" << endl; + } + } + if (n1 > n2) + { + cout << "n1 大于 n2" << endl; + } + return 0; +} diff --git a/day4/d13.cpp b/day4/d13.cpp new file mode 100644 index 0000000..27ddc2c --- /dev/null +++ b/day4/d13.cpp @@ -0,0 +1,52 @@ +// 重载 * 和 -> +// 注意: * 和 -> 的重载不能有参数 +#include +#include +#include + +using namespace std; + +class A +{ +private: + int x; + +public: + explicit A(int x) : x(x) {} + void printA() + { + cout << "x = " << x << endl; + } +}; + +class B +{ +private: + A *mA; + +public: + B(int x) : mA(new A(x)) + { + } + + A *operator->() + { + return mA; + } + A &operator*() + { + return *mA; + } +}; + +int main() +{ + B b(20); + // b -> 执行 B 类的 -> 重载,返回 A 类的对象的指针 + b->printA(); + + B b2(30); + // *b 执行 B 类的 * 重载函数,返回 A 类的对象 + (*b2).printA(); + return 0; +} diff --git a/day4/d1_2.cpp b/day4/d1_2.cpp new file mode 100644 index 0000000..ca75fc8 --- /dev/null +++ b/day4/d1_2.cpp @@ -0,0 +1,30 @@ +// 静态成员函数, 内部只能访问静态成员变量 +#include +#include +#include + +using namespace std; + +class A +{ +public: + int m; + static int x; + static void add(int n) + { + // m = 10; // error, 静态成员函数不能访问非静态成员 + x += n; + cout << "static x = " << x << endl; + } +}; + +int A::x = 20; // 静态变量的初始化 + +int main() +{ + A a1; + A::add(10); // static x = 30 + cout << "a1.x = " << a1.x << endl; // a1.x = 30 + + return 0; +} diff --git a/day4/d1_3.cpp b/day4/d1_3.cpp new file mode 100644 index 0000000..a5234a5 --- /dev/null +++ b/day4/d1_3.cpp @@ -0,0 +1,27 @@ +// 静态成员变量不占类对象的空间 +#include +#include +#include + +using namespace std; + +class A +{ +public: + int m; + static int x; + A(int m) + { + this->m = m; + } +}; + +// int A::x = 20; // 静态变量初始化 + +int main() +{ + A a1(3); + cout << "A size " << sizeof(A) << endl; // 同下 + cout << "a1 size " << sizeof(a1) << endl; // 4 Byte , 为 int m 的大小 + return 0; +} diff --git a/day4/d2.cpp b/day4/d2.cpp new file mode 100644 index 0000000..1f3dfca --- /dev/null +++ b/day4/d2.cpp @@ -0,0 +1,53 @@ +// 类的单例设计模式 +// 私有化构造函数和拷贝函数, 提供一个public的静态函数返回类的指针对象, 声明一个静态的类 +// 的指针对象。 +#include +#include +#include + +using namespace std; + +class A // 单例的类: 类的对象运行期间有且只有一个对象 +{ +private: + int x; + A(int x) { this->x = x; } + A(const A &other) + { + x = other.x; + } + +public: + static A *getInstance(int x = 0) + { + if (instance == NULL) + { + instance = new A(x); + } + return instance; + } + void show() + { + cout << "x = " << x << endl; + } + +public: + static A *instance; +}; + +A *A::instance = NULL; // 定义初始化,在静态全局区 + +int main() +{ + A *a1 = A::getInstance(20); + a1->show(); + + A *a2 = A::getInstance(); + a2->show(); + cout << "a1 addr = " << a1 << endl; + cout << "a2 addr = " << a2 << endl; + + delete A::instance; // 释放单例对象的空间 + + return 0; +} diff --git a/day4/d3.cpp b/day4/d3.cpp new file mode 100644 index 0000000..f523416 --- /dev/null +++ b/day4/d3.cpp @@ -0,0 +1,81 @@ +// 对象的存储 +// this 指针与链式编程(构造器模式) +#include +#include +#include + +using namespace std; + +class A +{ +private: + int a, b, c; + +public: + void setA(int a) + { + this->a = a; + } + void setB(int b) + { + this->b = b; + } + void setC(int c) + { + this->c = c; + } + void show() + { + cout << "a = " << a << ", b = " << b << ", c = " << c << endl; + } +}; + +class ABuilder +{ +private: + A *instance; + +public: + ABuilder() + { + instance = new A(); + } + ~ABuilder() + { + if (instance != NULL) + { + cout << "~ABuilder()" << endl; + delete instance; + } + } + +public: + ABuilder &a(int a) + { + instance->setA(a); + return *this; + } + ABuilder &b(int b) + { + instance->setB(b); + return *this; + } + ABuilder &c(int c) + { + instance->setC(c); + return *this; + } + A *build() + { + return instance; + } +}; + +int main() +{ + // 构建器设计模式: 构造产品,需要构造器一步一步的完成构造,最后 build() 出产品 + ABuilder builder; + A *a1 = builder.a(1).b(3).c(8).build(); + a1->show(); + return 0; +} diff --git a/day4/d4.cpp b/day4/d4.cpp new file mode 100644 index 0000000..4ddc297 --- /dev/null +++ b/day4/d4.cpp @@ -0,0 +1,38 @@ +// 当const修饰成员函数时,函数内不能修改普通成员变量,但可以修改mutable修饰的成员变量。 当const修饰类对象时,只能读成员变量,不能修改成员变量的值。可以调用const修饰的成员函数,不 +// 能调用普通成员函数 +#include +#include +#include + +using namespace std; + +class A +{ +public: + int x; + mutable int y; + +public: + void setXY(int x, int y) const + { + // this->x = x; // error + this->y = y; + } + void show() + { + cout << x << ", " << y << endl; + } +}; + +int main() +{ + A a1; + a1.setXY(1, 2); // const 函数,内部不修改非 mutable 的成员变量 + a1.show(); + + // const A a2; // 报错,const 变量必须存在初始值(右值) + const A a2 = A(); + a2.setXY(0, 30); // const 对象可以访问 const 的成员函数 + // a2.show(); // const 对象不能访问非 const 成员函数 + return 0; +} diff --git a/day4/d5.cpp b/day4/d5.cpp new file mode 100644 index 0000000..47414cd --- /dev/null +++ b/day4/d5.cpp @@ -0,0 +1,38 @@ +// 友元 +// 全局友元函数 +#include +#include +#include + +using namespace std; + +class B +{ + // 声明全局函数的友元 + friend void show(B &b); // 将全局的 show() 函数设置为当前类的友元函数 + +private: + int x; + +public: + B(int x) : x(x) {} + void show() + { + cout << "成员函数 x = " << x << endl; + } +}; + +// 全局的友元函数 +void show(B &b) +{ + // b 的私有成员 + cout << "全局友元函数 b.x = " << b.x << endl; +} + +int main() +{ + B b(100); + b.show(); // 成员函数 x = 100 + show(b); // 全局友元函数 b.x = 100 + return 0; +} diff --git a/day4/d6.cpp b/day4/d6.cpp new file mode 100644 index 0000000..85765b9 --- /dev/null +++ b/day4/d6.cpp @@ -0,0 +1,48 @@ +// 友元 +// 友元的类成员函数 +#include +#include +#include + +using namespace std; + +class B; + +class C +{ +public: + // 在此函数内,要访问 B 类中的所有成员,将此函数在 B 类中声明友元 + // 先声明,不能实现 + void showB(B &b); +}; + +class B +{ + // 声明友元的成员函数 + friend void C::showB(B &b); + +private: + int x; + +public: + B(int x) : x(x) {} + void show() + { + cout << "成员函数 x = " << x << endl; + } +}; + +// 定义或实现友元的成员函数 +void C::showB(B &b) +{ + cout << "友元的成员函数 b.x = " << b.x << endl; +} + +int main() +{ + B b(100); + b.show(); + C c; + c.showB(b); + return 0; +} diff --git a/day4/d6_2.cpp b/day4/d6_2.cpp new file mode 100644 index 0000000..49f8cdf --- /dev/null +++ b/day4/d6_2.cpp @@ -0,0 +1,43 @@ +// 友元类 +#include +#include +#include + +using namespace std; + +class B; + +class C +{ +public: + void showB(B &b); +}; + +class B +{ + friend class C; + +private: + int x; + +public: + B(int x) : x(x) {} + void show() + { + cout << "成员函数 x = " << x << endl; + } +}; + +void C::showB(B &b) +{ + cout << "友元类 b.x = " << b.x << endl; +} + +int main() +{ + B b(100); + b.show(); + C c; + c.showB(b); + return 0; +} diff --git a/day4/d8.cpp b/day4/d8.cpp new file mode 100644 index 0000000..0aa8e67 --- /dev/null +++ b/day4/d8.cpp @@ -0,0 +1,41 @@ +// 运算符重载 +// + 运算符 +#include +#include +#include + +using namespace std; + +class A +{ +private: + int x; + +public: + explicit A(int x) + { + this->x = x; + } + void show() + { + cout << x << endl; + } + // + 运算符重载,类成员函数,双目运算符,只需要一个参数 + A *operator+(A &other); +}; + +A *A::operator+(A &other) +{ + A *tmp = new A(this->x + other.x); + return tmp; +} + +int main() +{ + A a1(5), a2(6); + a1.show(); + A *a3 = a1 + a2; + a3->show(); + delete a3; + return 0; +} diff --git a/day4/d9.cpp b/day4/d9.cpp new file mode 100644 index 0000000..70bed10 --- /dev/null +++ b/day4/d9.cpp @@ -0,0 +1,75 @@ +// 运算符重载 +// ++、-- 运算符 +#include +#include +#include + +using namespace std; + +class A +{ +private: + int x; + +public: + explicit A(int x) + { + this->x = x; + } + void show() + { + cout << x << endl; + } + // ++ 运算符重载,类成员函数,单目运算符,++ 在前时不要参数,++ 在后需要一个占位参数 + A &operator++(int); + A &operator++(); + A *operator--(int); + A *operator--(); +}; + +A &A::operator++(int) // ++ 在后需要有占位参数 +{ + this->x++; + return *this; +} + +A &A::operator++() +{ + ++this->x; + return *this; +} + +A *A::operator--(int) +{ + A *tmp = new A(this->x--); + return tmp; +} + +A *A::operator--() +{ + A *tmp = new A(--this->x); + return tmp; +} + +int main() +{ + A a1(5); + a1.show(); + a1++; + a1.show(); + ++a1; + a1--; + a1.show(); + --a1; + a1.show(); + + A a2(8); + a2--; + a2--; + a2++; + ++a2; + --a2; + a2.show(); + + return 0; +} diff --git a/day4/homework/h6_2.cpp b/day4/homework/h6_2.cpp index e1008ab..9324bed 100644 --- a/day4/homework/h6_2.cpp +++ b/day4/homework/h6_2.cpp @@ -1,136 +1,9 @@ #include +using namespace std; + class ArrayList { private: - int *elements; // 存储元素的数组 - int capacity; // 数组的容量 - int count; // 当前元素的数量 - -public: - ArrayList() - { - capacity = 10; // 初始容量为10 - elements = new int[capacity]; - count = 0; - } - - ~ArrayList() - { - delete[] elements; - } - - void add(int value) - { - if (count == capacity) - { - // 如果数组已满,扩展容量为原来的两倍 - int newCapacity = capacity * 2; - int *newElements = new int[newCapacity]; - for (int i = 0; i < count; i++) - { - newElements[i] = elements[i]; - } - delete[] elements; - elements = newElements; - capacity = newCapacity; - } - elements[count] = value; - count++; - } - - void remove(int index) - { - if (index >= 0 && index < count) - { - for (int i = index; i < count - 1; i++) - { - elements[i] = elements[i + 1]; - } - count--; - } - } - - int get(int index) - { - if (index >= 0 && index < count) - { - return elements[index]; - } - return -1; // 返回一个特殊值表示索引无效 - } - - void print() - { - for (int i = 0; i < count; i++) - { - std::cout << elements[i] << " "; - } - std::cout << std::endl; - } - - int size() - { - return count; - } - - void sort(bool reversed = false) - { - for (int i = 0; i < count - 1; i++) - { - for (int j = 0; j < count - i - 1; j++) - { - if (reversed) - { - if (elements[j] < elements[j + 1]) - { - int temp = elements[j]; - elements[j] = elements[j + 1]; - elements[j + 1] = temp; - } - } - else - { - if (elements[j] > elements[j + 1]) - { - int temp = elements[j]; - elements[j] = elements[j + 1]; - elements[j + 1] = temp; - } - } - } - } - } -}; - -int main() -{ - ArrayList list; - - list.add(5); - list.add(2); - list.add(8); - list.add(1); - - std::cout << "Original list: "; - list.print(); - - std::cout << "Size: " << list.size() << std::endl; - - std::cout << "Element at index 2: " << list.get(2) << std::endl; - - list.remove(1); - - std::cout << "After removing element at index 1: "; - list.print(); - - std::cout << "Sorted list in ascending order: "; - list.sort(); - list.print(); - - std::cout << "Sorted list in descending order: "; - list.sort(true); - list.print(); - - return 0; -} + int +}; \ No newline at end of file