Review cpp day07
Posted 达少Rising
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Review cpp day07相关的知识,希望对你有一定的参考价值。
回顾:
Review cpp day01
Review cpp day02
Review cpp day03
Review cpp day04
Review cpp day05
Review cpp day06
十九、成员指针//了解
1、成员变量指针
- 1)定义:
类型 类名::*指针变量名 = &类名::变量;
- 2)使用
- 对象.*成员指针变量名;
注: ".*"称为成员指针解引用操作符 - 对象指针->*成员指针变量名;
注: "->*"称为间接成员指针解引用操作符
- 对象.*成员指针变量名;
01menptr.cpp
#include <iostream>
using namespace std;
class Student{
public:
Student(const string& name):m_name(name){}
string m_name;
};
int main(void){
string Student::*pname = &Student::m_name;
Student s("张飞");
Student* ps = new Student("赵云");
cout << s.*pname << endl;//张飞
cout << ps->*pname << endl;//赵云
delete ps;
return 0;
}
2、成员函数指针
- 1)定义:
返回类型 (类名::*成员函数指针)(形参表) = &类名::成员函数名;
- 2)使用
- (对象.*成员函数指针)(实参表);
- (对象指针->*成员函数指针)(实参表);
02menptr.cpp
#include <iostream>
using namespace std;
class Student{
public:
Student(const string& name):m_name(name){}
void who(void){
cout << m_name << endl;
}
string m_name;
};
int main(void){
void (Student::*pwho)(void) = &Student::who;
Student s("张飞");
Student* ps = new Student("赵云");
(s.*pwho)();//张飞
(ps->*pwho)();//赵云
delete ps;
return 0;
}
二十、操作符重载
eg:复数 x+yi, 实现(1+2i) + (3+4i) = 4 + 6i
1、双目操作符的重载 L#R
1.1、运算类的双目操作符:+ - …
- 左右操作数既可以是左值也可以是右值
- 表达式结构是右值
- 两种实现方式:
- 1)成员函数形式
L#R的表达式可以被编译器翻译成L.operator#®这样成员函数调用形式,该函数的返回结果即使表达式的结果。 - 2)全局函数形式
L#R的表达式可以被编译器翻译成::operator#(L, R)这样全局函数调用形式,该函数的返回结果即使表达式的结果。
注: 使用“friend”关键字,可以把一个全局函数声明为某个类的友元,友元函数可以访问类中任何成员。
- 1)成员函数形式
03complex.cpp(第一种实现方式)
#include <iostream>
using namespace std;
class Complex{
public:
Complex(int r, int i):m_r(r), m_i(i){}
void print(void)const{
cout << m_r << '+' << m_i << 'i' << endl;
}
//c1+c2==>c1.operator+(c2)
/*
*const关键字的意义:
*1)修饰返回值,为了返回右值
*2)常引用,为了支持常量型右操作数(右值)
*3)常函数,为了支持常量型左操作数(左值)
*/
const Complex operator+(const Complex& c)const{
Complex res(m_r+c.m_r, m_i+c.m_i);
return res;
}
private:
int m_r;//实部
int m_i;//虚部
};
int main(void){
Complex c1(1, 2);
Complex c2(3, 4);
c1.print();
c2.print();
c1.operator+(c2);
Complex c3 = c1 + c2;
c3.print();//4+6i
return 0;
}
03complex.cpp(第二种实现方式)
#include <iostream>
using namespace std;
class Complex{
public:
Complex(int r, int i):m_r(r), m_i(i){}
void print(void)const{
cout << m_r << '+' << m_i << 'i' << endl;
}
//c1+c2==>c1.operator+(c2)
/*
*const关键字的意义:
*1)修饰返回值,为了返回右值
*2)常引用,为了支持常量型右操作数(右值)
*3)常函数,为了支持常量型左操作数(左值)
*/
const Complex operator+(const Complex& c)const{
Complex res(m_r+c.m_r, m_i+c.m_i);
return res;
}
private:
int m_r;//实部
int m_i;//虚部
//友元函数可以访问类中的私有成员
friend const Complex operator-(const Complex& l, const Complex& r);
};
const Complex operator-(const Complex& l, const Complex& r){
Complex res(l.m_r-r.m_r, l.m_i-r.m_i);
return res;
}
int main(void){
Complex c1(1, 2);
Complex c2(3, 4);
c1.print();
c2.print();
c1.operator+(c2);
Complex c3 = c1 + c2;
c3.print();//4+6i
//::operator-(c2, c1)
c3 = c2 - ci;
c3.print();//2+2i
return 0;
}
1.2、赋值类的双目操作符:+= -= …
- 左操作数必须是左值,右操作数可以是左值也可以是右值
- 表达式的结果是左值,就是左操作数的自身。
int a = 3, b= 5;
(a += b) = 10;//a+=b,a=10
(a += 5) = 10;
- 两种实现方式:
- 1)成员函数形式
L # R ==》L.operator#(R)
- 2)全局函数形式
L # R ==》::operator#(L, R)
- 1)成员函数形式
04complex.cpp
#include <iostream>
using namespace std;
class Complex{
public:
Complex(int r, int i):m_r(r), m_i(i){}
void print(void)const{
cout << m_r << '+' << m_i << 'i' << endl;
}
//+=:成员函数形式
Comple& operator+=(const Complex& c){
m_r += c.m_r;
m_i += c.m_i;
return *this;
}
//友元函数可以把定义直接写在类的内部,但是它不属于类,本质上还是全局函数
friend Complex& operator-=(Complex& l, const Complex& r){
l.m_r -= r.m_r;
l.m_i -= r.m_i;
return l;
}
private:
int m_r;//实部
int m_i;//虚部
};
int main(void){
Complex c1(1, 2);
Complex c2(3, 4);
c1 += c2;//c1.operator+=(c2)
c1.print();//4+6i
c1 -= c2;//::operator-=(c1, c2)
c1.print();//1+2i
return 0;
}
2、单目操作符重载#O
2.1、计算类的单目操作符:-(取负) ~…
- 操作数可以是左值也可以是右值
- 表达式结果是右值
- 两种实现方式:
- 1)成员函数形式:
#O ==》O.operator#();
- 2)全局函数形式
#O ==》::operator#(O);
- 1)成员函数形式:
05Integer.cpp
#include <iostream>
using namespace std;
class Integer{
public:
Integer(int i=0):m_i(i){}
void print(void)const{
cout << m_i << endl;
}
//-:成员函数形式
const Integer operator-(void)const{
Integer res(-m_i);
return res;
}
//~:全局函数形式(自定义表示乘方)
friend const Integer operator~(const Integer& i){
Integer res(i.m_i * i.m_i);
return res;
}
private:
int m_i;
};
int main(void){
Integer i(100);
Integer j = -i;//i.operator-();
j.print();//100
j = ~i;
j.print();//10000
return 0;
}
2.2、自增减单目操作符:前后++、--
- 1)前
++、--
- 操作数必须是左值;
- 表达式结果也是左值,就是操作数的自身。
- 两种实现方式:
- 成员函数 #O==》O.operator#()
- 全局函数 #O==》::operator#(O)
int a = 1;
cout << ++a << endl;//2
cout << a << endl;//2
++a = 10;//ok
cout << a << endl;//10
++++++a;//ok
cout << a << endl;//13
- 2)后
++、--
- 操作数必须是左值;
- 表达式结果是右值,是操作数自增减前的副本。
- 两种实现方式:
- 成员函数 O#==》O.operator#(哑元)
- 全局函数 O#==》::operator#(O,哑元)
注: 哑元只是为了区分前、后++, --
int a = 1;
cout << a++ << endl;//1
cout << a << endl;//2
06Integer.cpp
#include <iostream>
using namespace std;
class Integer{
public:
Integer(int i=0):m_i(i){}
void print(void)const{
cout << m_i << endl;
}
//前++:成员函数形式
Integer& operator++(void){
++m_i;
return *this;
}
//前--:全局函数形式
friend Integer& operator--(Integer& i){
--i.m_i;
return i;
}
//后++:成员函数形式
const Integer operator++(int/*哑元*/){
Integer old = *this;
++*this;//++m_i;
return old;
}
//后--:全局函数形式
friend const Integer operator--(Integer& i, int/*哑元*/){
Integer old = i;
i--;
return old;
}
private:
int m_i;
};
int main(void){
Integer i(100);
Integer j = ++i;//i.operator++()
i.print();//
j.print();//
j = ++++++i;
i.print();//104
j.print();//104
j = --i;//::operator--(i)
i.print();//103
j.print();//103
j = ------i;
i.print();//100
j.print();//100
j = i++;//i.operator++(0)
i.print();//101
j.print();//100
j = i--;//::operator--(i, 0)
i.print();//100
j.print();//101
return 0;
}
3、插入和提取操作符:<< >>
- 功能:实现自定义类型的对象的直接输入和输出
注: 只能用全局函数形式,因为ostream cout 与 istream cin
是c++的标准库中的东西,难以改变源码,所以只能用全局函数形式::operator<<(cout/cin, a);
07io_operator.cpp
#include <iostream>
ostream cout;
istream cin;
friend ostream& operator<<(ostream& os, const RIGHT& right){......}
friend istream& operator>>(istream& is, RIGHT& right){......}
cout << a << b << c;//cout<< a cout << b << c; cout << a cout << b cout << c;
cin >> a >> b >> c;
03complex.cpp
#include <iostream>
using namespace std;
class Complex{
public:
Complex(int r, int i):m_r(r), m_i(i){}
friend ostream& operator<<(ostream& os, const Complex& c){
os << c.m_r << "+" << c.m_i << "i";
return os;
}
friend istream& operator>>(istream& is, Complex& c){
is >> c.m_r >> c.m_i;
return is;
}
private:
int m_r;//实部
int m_i;//虚部
};
int main(void){
Complex c1(1, 2);
Complex c2(3, 4);
//::operator << (cout, c1);
cout << c1 << endl;
cout << c1 << ',' << c2 << endl;
Complex c3(0, 0);
cout << "请输入一个复数的(实部和虚部):";
cin >> c3;//::operator>>(cin, c3);
cout << c3 << endl;
return 0;
}
- 练习:实现一个3*3矩阵,支持如下操作符重载:+ - += -(负) <<(输出)
class M33{
public:
M33(void){
for(int i=0; i<3; i++){
for(int j=0; j<3; j++0){
m_a[i][j] = 0;
}
}
}
M33(int a[][3]){
for(int i=0; i<3; i++){
for(int j=0; j<3; j++0){
m_a[i][j] = a[i][j];
}
}
}
private:
int m_a[3][3];
};
int main(void){
int a1[3][3] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
M33 m1(a1);
int a2[3][3] = {9, 8, 7, 6, 5, 4, 3, 2, 1};
M33 m2(a2);
return 0;
}
08M33.cpp
#include <iostream>
#include <iomanip>//setw(4)引用的头文件
using namespace std;
class M33{
public:
M33(void){
for(int i=0; i<3; i++){
for(int j=0; jReview cpp day09