Skip to content

Commit c6f7dbb

Browse files
committed
Updated to Chapter 12, Section 3
1 parent 1ace8be commit c6f7dbb

File tree

16 files changed

+691
-258
lines changed

16 files changed

+691
-258
lines changed

.vscode/Test.cpp

+14-5
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,20 @@
22
#include<exception>
33
#include<stdexcept>
44
#include<vector>
5-
void func()noexcept { }
6-
void func(int n) { }
5+
class Complex {
6+
double real;
7+
double image;
8+
public:
9+
Complex(double r=0,double i=0):real{r},image{i}{}
10+
Complex operator+(const Complex &c)const{
11+
return Complex(real+c.real,image+c.image);
12+
}
13+
// friend Complex operator+(const Complex &c1, const Complex &c2){
14+
// return Complex(c1.real+c2.real,c1.image+c2.image);
15+
// }
16+
};
717
int main() {
8-
std::vector<int> vec(3); //vec的长度为3
9-
std::cout << noexcept(vec.at(2))<<std::endl;
10-
std::cout << noexcept(vec.at(3))<<std::endl;
18+
Complex a(1,2);
19+
2+a;
1120
return 0;
1221
}

.vscode/Test.exe

-43.8 KB
Binary file not shown.

.vscode/settings.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
"set": "cpp",
5959
"valarray": "cpp",
6060
"xhash": "cpp",
61-
"xtree": "cpp"
61+
"xtree": "cpp",
62+
"string": "cpp"
6263
}
6364
}

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
55
此项目第一阶段计划(前七章)已经完成!
66

7-
### 当前进度:第十一章完成。参见[Preview](https://github.com/cppHusky/cppHusky-cpp-Tutorial/releases/tag/preview-0-0-11)
7+
### 当前进度:第十二章完成。参见[Preview](https://github.com/cppHusky/cppHusky-cpp-Tutorial/releases/tag/preview-0-0-12)
88

99
我为此规划了一个大致的编章结构,参见[Structure.md](https://github.com/cppHusky/cppHusky-cpp-Tutorial/blob/main/Structure.md)
1010

code_in_book/12.2-12.3/Definition.tpp

+183
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
//matrix类模板的成员函数定义
2+
template<typename T>
3+
user::matrix<T>::matrix(size_type n, size_type m) : N {n}, M {m} {
4+
//常量成员必须通过初始列来初始化
5+
_element.resize(N); //先改变_element的大小,这是行数
6+
for (auto &row : _element) //这样写方便些,注意row是引用形式
7+
row.resize(M); //对每一行进行resize,M为列数
8+
//resize之后每个元素都是默认值value_type{},这样,一个矩阵构造就完成了
9+
}
10+
template<typename T>
11+
user::matrix<T>::matrix(
12+
std::initializer_list<std::initializer_list<value_type>> ilist
13+
) : N {ilist.size()}, M {user::max_column(ilist)} {
14+
//在初值列中通过ilist和辅助函数确定行/列数
15+
_element.resize(N); //同样的道理,先改变_element的大小,代表行数
16+
size_type i {0}; //循环变量
17+
for (const auto &row : ilist) { //访问initializer_list不能用下标运算符
18+
_element[i].resize(M); //对每一行进行resize,M代表列数
19+
size_type j {0}; //也是循环变量
20+
for (const auto &x : row) {
21+
_element[i][j++] = x; //注意++是后缀形式
22+
}
23+
++i; //别忘了循环迭代
24+
} //这样,一个矩阵构造就完成了
25+
}
26+
template<typename T>
27+
auto user::matrix<T>::operator()(size_type i, size_type j) -> reference {
28+
if (i >= N) {
29+
std::string msg {"Error: Row index "};
30+
msg += std::to_string(i) + " >= " + std::to_string(N);
31+
throw typename matrix<T>::index_error {msg};
32+
//靠加法运算符疯狂拼接,然后抛出
33+
}
34+
if (j >= M) {
35+
std::string msg {"Error: Column index "};
36+
msg += std::to_string(j) + " >= " + std::to_string(M);
37+
throw typename matrix<T>::index_error {msg}; //同上
38+
}
39+
return _element[i][j];
40+
}
41+
template<typename T>
42+
auto user::matrix<T>::operator()(size_type i, size_type j)const
43+
-> const_reference {
44+
if (i >= N) {
45+
std::string msg {"Error: Row index "};
46+
msg += std::to_string(i) + " >= " + std::to_string(N);
47+
throw matrix<T>::index_error {msg};
48+
}
49+
if (j >= M) {
50+
std::string msg {"Error: Column index "};
51+
msg += std::to_string(j) + " >= " + std::to_string(M);
52+
throw matrix<T>::index_error {msg};
53+
}
54+
return _element[i][j];
55+
}
56+
template<typename T>
57+
auto user::matrix<T>::operator*(const T &val) -> matrix {
58+
matrix mat {*this}; //用*this来拷贝构造mat
59+
for (auto &row : mat._element) //遍历每一行,每一个row都是一个valarray引用
60+
row *= val; //std::valarray特有的乘赋值功能
61+
return mat; //返回值
62+
}
63+
template<typename T>
64+
auto user::matrix<T>::transpose()const -> matrix{
65+
matrix mat(M,N); //行列数颠倒
66+
for (size_type i = 0; i < N; ++i)
67+
for (size_type j = 0; j < M; ++j)
68+
mat(j,i) = operator()(i,j); //注意i,j别写错了,想清楚
69+
return mat;
70+
}
71+
template<typename T>
72+
auto user::matrix<T>::size()const noexcept
73+
-> std::pair<size_type, size_type> {
74+
return typename std::pair<size_type, size_type> {N, M}; //不需要typename,但可以有
75+
}
76+
//matrix类模板相关的非成员函数定义
77+
template<typename T>
78+
auto user::operator+(const matrix<T> &lhs, const matrix<T> &rhs)
79+
-> matrix<T> {
80+
if (lhs.N != rhs.N || lhs.M != rhs.M) {
81+
std::string msg {"Cannot add "};
82+
msg += std::to_string(lhs.N) + " * " + std::to_string(lhs.M)
83+
+ " matrix to " + std::to_string(rhs.N)
84+
+ " * " + std::to_string(rhs.M) + "matrix";
85+
throw typename matrix<T>::invalid_plus {msg};
86+
}
87+
matrix mat {lhs}; //用lhs为mat赋值
88+
for (std::size_t i = 0; i < lhs.N; ++i)
89+
mat._element[i] += rhs._element[i]; //再加上rhs的每一行
90+
return mat;
91+
}
92+
template<typename T>
93+
auto user::operator-(const matrix<T> &lhs, const matrix<T> &rhs)
94+
-> matrix<T> {
95+
if (lhs.N != rhs.N || lhs.M != rhs.M) {
96+
std::string msg {"Cannot add "};
97+
msg += std::to_string(lhs.N) + " * " + std::to_string(lhs.M)
98+
+ " matrix from " + std::to_string(rhs.N)
99+
+ " * " + std::to_string(rhs.M) + "matrix";
100+
throw typename matrix<T>::invalid_plus {msg};
101+
}
102+
matrix mat {lhs};
103+
for (std::size_t i = 0; i < lhs.N; ++i)
104+
mat._element[i] -= rhs._element[i]; //再减去rhs的每一行
105+
return mat;
106+
}
107+
template<typename T>
108+
auto user::operator*(const matrix<T> &lhs, const matrix<T> &rhs)
109+
-> matrix<T> {
110+
if (lhs.M != rhs.N) {
111+
std::string msg {"Cannot multiply matrix with "};
112+
msg += std::to_string(lhs.M) + " columns by matrix with "
113+
+ std::to_string(rhs.N) + " rows";
114+
throw typename matrix<T>::invalid_multiplies{msg};
115+
}
116+
matrix<T> mat(lhs.N, rhs.M); //新建一个空的矩阵
117+
for (std::size_t i = 0; i < lhs.N; ++i)
118+
for (std::size_t j = 0; j < rhs.M; ++j)
119+
for (std::size_t k = 0; k < lhs.M; ++k)
120+
mat(i,j) += lhs(i,k) * rhs(k,j); //三重循环,就不讲了
121+
return mat;
122+
}
123+
template<typename T>
124+
auto user::operator*(const T &value, const matrix<T> &mat) -> matrix<T> {
125+
return mat * value; //节省代码,就这样写了
126+
}
127+
template<typename T>
128+
bool user::operator<(const matrix<T> &lhs, const matrix<T> &rhs) {
129+
if (lhs.N != rhs.N || lhs.M != rhs.M) {
130+
std::string msg {"Cannot compare "};
131+
msg += std::to_string(lhs.N) + " * " + std::to_string(lhs.M)
132+
+ " matrix with " + std::to_string(rhs.N) + " * "
133+
+ std::to_string(rhs.M) + " matrix";
134+
throw typename matrix<T>::invalid_compare {msg};
135+
}
136+
for (std::size_t i = 0; i < lhs.N; ++i)
137+
if (lhs._element[i] < rhs._element[i])
138+
return true;
139+
else if (lhs._element[i] > rhs._element[i])
140+
return false;
141+
return false;
142+
}
143+
template<typename T>
144+
bool user::operator>(const matrix<T> &lhs, const matrix<T> &rhs) {
145+
return rhs < lhs;
146+
}
147+
template<typename T>
148+
bool user::operator<=(const matrix<T> &lhs, const matrix<T> &rhs) {
149+
return !(rhs < lhs);
150+
}
151+
template<typename T>
152+
bool user::operator>=(const matrix<T> &lhs, const matrix<T> &rhs) {
153+
return !(lhs < rhs);
154+
}
155+
template<typename T>
156+
bool user::operator!=(const matrix<T> &lhs, const matrix<T> &rhs) {
157+
if (lhs.N != rhs.N || lhs.M != rhs.M) {
158+
std::string msg {"Cannot compare "};
159+
msg += std::to_string(lhs.N) + " * " + std::to_string(lhs.M)
160+
+ " matrix with " + std::to_string(rhs.N) + " * "
161+
+ std::to_string(rhs.M) + " matrix";
162+
throw typename matrix<T>::invalid_compare {msg};
163+
}
164+
for (std::size_t i = 0; i < lhs.N; ++i)
165+
if (lhs._element[i] != rhs._element[i])
166+
return true;
167+
return false;
168+
}
169+
template<typename T>
170+
bool user::operator==(const matrix<T> &lhs, const matrix<T> &rhs) {
171+
return !(lhs != rhs);
172+
}
173+
//辅助函数定义
174+
template<typename T>
175+
std::size_t user::max_column(
176+
const std::initializer_list<std::initializer_list<T>> &ilist
177+
) {
178+
std::size_t result {}; //初始化为0
179+
for (auto row : ilist)
180+
if(result < row.size())
181+
result = row.size();
182+
return result; //返回的就是二维列表各行的最大值
183+
}

0 commit comments

Comments
 (0)