day4: static 静态成员, 类的单例设计模式, 对象的存储(this 指针与链式编程, const 修饰成员函数与类对象), 友元, 运算符重载

This commit is contained in:
flykhan 2023-07-28 08:57:54 +08:00
parent 7b786b9b92
commit f5c016c6bb
17 changed files with 681 additions and 131 deletions

View File

@ -7,3 +7,5 @@
#### day2: const 和#define 的区别, 引用(reference) 【重要】, 内联函数, 函数的默认值参数, 函数的占位参数, 函数重载和 extern "c", 类与对象的概念, 面向对象程序设计案例 #### day2: const 和#define 的区别, 引用(reference) 【重要】, 内联函数, 函数的默认值参数, 函数的占位参数, 函数重载和 extern "c", 类与对象的概念, 面向对象程序设计案例
#### day3: 对象的构造与析构, 构造函数的分类与调用, 拷贝构造函数的调用时机, 构造函数的调用规则, 深拷贝和浅拷贝, 多个对象的构造和析构(初始化列表, 类对象作为成员), explicit 关键字(禁止隐式转换), 动态创建对象(malloc/realloc/calloc 在堆中创建空间, new 关键字), 扩展 new 和 delete, #### day3: 对象的构造与析构, 构造函数的分类与调用, 拷贝构造函数的调用时机, 构造函数的调用规则, 深拷贝和浅拷贝, 多个对象的构造和析构(初始化列表, 类对象作为成员), explicit 关键字(禁止隐式转换), 动态创建对象(malloc/realloc/calloc 在堆中创建空间, new 关键字), 扩展 new 和 delete,
#### day4: static 静态成员, 类的单例设计模式, 对象的存储this 指针与链式编程, const 修饰成员函数与类对象), 友元, 运算符重载

26
day4/d1.cpp Normal file
View File

@ -0,0 +1,26 @@
// 类的静态成员变量的声明、初始化与访问
#include <iostream>
#include <cstring>
#include <cstdlib>
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;
}

32
day4/d10.cpp Normal file
View File

@ -0,0 +1,32 @@
// 重载 C++ 的 << 输出流运算符
#include <iostream>
#include <cstring>
#include <cstdlib>
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;
}

39
day4/d11.cpp Normal file
View File

@ -0,0 +1,39 @@
// 重载 C++ 的 >> 输入流运算符
#include <iostream>
#include <cstring>
#include <cstdlib>
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;
}

52
day4/d12.cpp Normal file
View File

@ -0,0 +1,52 @@
// 重载运算符
#include <iostream>
#include <cstring>
#include <cstdlib>
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;
}

52
day4/d13.cpp Normal file
View File

@ -0,0 +1,52 @@
// 重载 * 和 ->
// 注意: * 和 -> 的重载不能有参数
#include <iostream>
#include <cstring>
#include <cstdlib>
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;
}

30
day4/d1_2.cpp Normal file
View File

@ -0,0 +1,30 @@
// 静态成员函数, 内部只能访问静态成员变量
#include <iostream>
#include <cstring>
#include <cstdlib>
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;
}

27
day4/d1_3.cpp Normal file
View File

@ -0,0 +1,27 @@
// 静态成员变量不占类对象的空间
#include <iostream>
#include <cstring>
#include <cstdlib>
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;
}

53
day4/d2.cpp Normal file
View File

@ -0,0 +1,53 @@
// 类的单例设计模式
// 私有化构造函数和拷贝函数, 提供一个public的静态函数返回类的指针对象 声明一个静态的类
// 的指针对象。
#include <iostream>
#include <cstring>
#include <cstdlib>
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;
}

81
day4/d3.cpp Normal file
View File

@ -0,0 +1,81 @@
// 对象的存储
// this 指针与链式编程(构造器模式)
#include <iostream>
#include <cstring>
#include <cstdlib>
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;
}

38
day4/d4.cpp Normal file
View File

@ -0,0 +1,38 @@
// 当const修饰成员函数时函数内不能修改普通成员变量但可以修改mutable修饰的成员变量。 当const修饰类对象时只能读成员变量不能修改成员变量的值。可以调用const修饰的成员函数
// 能调用普通成员函数
#include <iostream>
#include <cstring>
#include <cstdlib>
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;
}

38
day4/d5.cpp Normal file
View File

@ -0,0 +1,38 @@
// 友元
// 全局友元函数
#include <iostream>
#include <cstring>
#include <cstdlib>
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;
}

48
day4/d6.cpp Normal file
View File

@ -0,0 +1,48 @@
// 友元
// 友元的类成员函数
#include <iostream>
#include <cstring>
#include <cstdlib>
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;
}

43
day4/d6_2.cpp Normal file
View File

@ -0,0 +1,43 @@
// 友元类
#include <iostream>
#include <cstring>
#include <cstdlib>
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;
}

41
day4/d8.cpp Normal file
View File

@ -0,0 +1,41 @@
// 运算符重载
// + 运算符
#include <iostream>
#include <cstring>
#include <cstdlib>
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;
}

75
day4/d9.cpp Normal file
View File

@ -0,0 +1,75 @@
// 运算符重载
// ++、-- 运算符
#include <iostream>
#include <cstring>
#include <cstdlib>
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;
}

View File

@ -1,136 +1,9 @@
#include <iostream> #include <iostream>
using namespace std;
class ArrayList class ArrayList
{ {
private: private:
int *elements; // 存储元素的数组 int
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;
}