文章目录

  • 1 不包含指针的class写法细节
    • 1.1 overloading
    • 1.2 构造函数放在private区域
    • 1.3 const成员函数
    • 1.4 传入参数都使用Reference
    • 1.5 返回参数尽量使用reference,有的不能
    • 1.6 friend
    • 1.7 运算符重载 —— 成员函数写法
    • 1.8 运算符重载 —— 非成员函数写法
    • 1.9 代码实践和注释总结

详情可以参看 github资料
下面是简介和代码注释。

要写正确,大气的代码。—— 侯捷

1 不包含指针的class写法细节

1.1 overloading

  • 构造函数1和2不能同时存在,意思是相同的,只是写法不同
  • 写构造函数的时候,一定要主要这个问题,意思不能重复
  • real的const版本和非const版本同名,但是不同意思,编译器认为不同,为overloading

1.2 构造函数放在private区域

  • singleton设计模式中用到

1.3 const成员函数

函数体里面不改变数据,就加上const,否则用户在使用的时候,给object加上const,调用那些非const成员函数会导致编译不通过。

代码验证

#include <iostream>class Complex {public:Complex(double r = 0, double i = 0) : re(r), im(i) {}double  getImage()const { return im; }double getReal() const{ return re; };private:double re, im;
};using namespace std;
int main() {const Complex complex;cout<<complex.getReal()<<endl;return 0;
}

如果不加const,调用会出现如下提示信息

1.4 传入参数都使用Reference

  • 传Reference的时候,需要修改这个参数,就不加const
void setZero (complex&);
  • 不需要修改传入参数,就加const
// example 1
Complex& operator += (const complex&);
// example 2: 第一个不能家const,第二个可以加
ostream& operator << (ostream& os, const complex& x);

1.5 返回参数尽量使用reference,有的不能

除了local变量不能返回Reference,其他的都可以,也就是只要已经有地方存储的变量才可以。

上图可以返回Reference,因为ths相对函数来讲,是一个非local变量

1.6 friend

自由取得类内private成员,不适用函数简洁拿数据,会比较快

相同的class的各个objects互为friends,图中的func的写法是合理的,虽然直接访问了私有成员

1.7 运算符重载 —— 成员函数写法


this不能明着写出来传入,但是是隐藏的,可以直接使用的

使用者没有连串使用的时候,返回void就行,但是为了考虑更好的设计类,我们使用返回Reference,支持连串使用

1.8 运算符重载 —— 非成员函数写法

对于输入输出流操作符,必定是非成员函数写法。



1.9 代码实践和注释总结

#ifndef __MYCOMPLEX__
#define __MYCOMPLEX__#include <iostream>class Complex;Complex &
__doapl(Complex *ths, const Complex &r);Complex &
__doami(Complex *ths, const Complex &r);Complex &
__doaml(Complex *ths, const Complex &r);class Complex {public:// 默认参数// 列表初始化,相比body内赋值少了一层运算Complex(double r = 0, double i = 0) : re(r), im(i) {}//--------------------------------------------------------// 【总结】运算符重载写在类内还是类外// 0. 想要链式操作,那么就return by reference。此外,有的只能//    return by value,有的只能return by reference// 1. 流操作符必须写在类外// 2. 对于一元运算符,一般都是写在类外// 3. 对于二元运算符,如果第一个参数(左边的那个)是class类型的object//    那么可以写在类内,也可以写在类外,如果有类内类外两种,会优先调用//    类内成员函数// 4. 对于二元运算符,如果第一个参数(左边的那个)不是class类型的object//    必须写成类外函数//--------------------------------------------------------// 类内操作符重载,表面看传入一个参数,事实上是(this, const Complex&)两个参数// return Reference是为了考虑用户的链式操作,此时一定是类内成员函数Complex &operator+=(const Complex &);Complex &operator-=(const Complex &);Complex &operator*=(const Complex &);Complex &operator/=(const Complex &);//未实现// 必须return value// 有类内和类外两种函数写法,如果两种都有,优先调用类内成员函数写法// 表面看传入一个参数,事实上是(this, const Complex&)两个参数Complex operator+(const Complex &complex) {std::cout << "I am a class member function!\n";return {re + complex.getReal(), im + complex.getImage()};}// const成员函数的使用,是为了考虑用户将class实例化const对象的时候// 如果调用该函数,则会编译报错,显示非const成员函数// 所以如果是不改变变量值的函数,直接写成const形式// 显得大气// getdouble getReal() const { return re; }double getImage() const { return im; }// setvoid setReal(const double &r) { re = r; }void setImage(const double &i) { im = i; }private:double re, im;// friend函数可以通过实例化的object直接访问私有变量,// 好处是不需要通过接口函数,少了一层开销friend Complex &__doapl(Complex *, const Complex &);friend Complex &__doami(Complex *, const Complex &);friend Complex &__doaml(Complex *, const Complex &);
};//--------------------------------------------------------
// friend member function
//--------------------------------------------------------
// class body内自动inline,类外需要手动inline
inline Complex &
__doapl(Complex *ths, const Complex &r) {ths->re += r.re;ths->im += r.im;return *ths;
}inline Complex &
Complex::operator+=(const Complex &r) {return __doapl(this, r);
}inline Complex &
__doami(Complex *ths, const Complex &r) {ths->re -= r.re;ths->im -= r.im;return *ths;
}inline Complex &
Complex::operator-=(const Complex &r) {return __doami(this, r);
}inline Complex &
__doaml(Complex *ths, const Complex &r) {double f = ths->re*r.re - ths->im*r.im;ths->im = ths->re*r.im + ths->im*r.re;ths->re = f;return *ths;
}inline Complex &
Complex::operator*=(const Complex &r) {return __doaml(this, r);
}//--------------------------------------------------------
// 类外全局函数
//--------------------------------------------------------
inline double
imag(const Complex &x) {return x.getImage();
}inline double
real(const Complex &x) {return x.getReal();
}//--------------------------------------------------------
// 类外操作符重载
//--------------------------------------------------------// 输入输出流操作符只能在类外重载
// 返回引用是为了链式操作
std::ostream &operator<<(std::ostream &os, const Complex &x) {return os << '(' << real(x) << ',' << imag(x) << ')';
}inline Complex
operator+(const Complex &x, const Complex &y) {return Complex(real(x) + real(y), imag(x) + imag(y));
}// !! 这个写法其实也可以写在类内
inline Complex
operator+(const Complex &x, double y) {return Complex(real(x) + y, imag(x));
}// !! 这个就只能写在类外
inline Complex
operator+(double x, const Complex &y) {return Complex(x + real(y), imag(y));
}inline Complex
operator-(const Complex &x, const Complex &y) {return Complex(real(x) - real(y), imag(x) - imag(y));
}inline Complex
operator-(const Complex &x, double y) {return Complex(real(x) - y, imag(x));
}inline Complex
operator-(double x, const Complex &y) {return Complex(x - real(y), -imag(y));
}inline Complex
operator*(const Complex &x, const Complex &y) {return Complex(real(x)*real(y) - imag(x)*imag(y),real(x)*imag(y) + imag(x)*real(y));
}inline Complex
operator*(const Complex &x, double y) {return Complex(real(x)*y, imag(x)*y);
}inline Complex
operator*(double x, const Complex &y) {return Complex(x*real(y), x*imag(y));
}Complex
operator/(const Complex &x, double y) {return Complex(real(x)/y, imag(x)/y);
}inline Complex
operator+(const Complex &x) {return x;
}// 这个一元操作符,也是只能写在类外
inline Complex
operator-(const Complex &x) {return Complex(-real(x), -imag(x));
}// 可以写在类内
inline bool
operator==(const Complex &x, const Complex &y) {return real(x) == real(y) && imag(x) == imag(y);
}inline bool
operator==(const Complex &x, double y) {return real(x) == y && imag(x) == 0;
}// 只能类外
inline bool
operator==(double x, const Complex &y) {return x == real(y) && imag(y) == 0;
}inline bool
operator!=(const Complex &x, const Complex &y) {return real(x) != real(y) || imag(x) != imag(y);
}inline bool
operator!=(const Complex &x, double y) {return real(x) != y || imag(x) != 0;
}inline bool
operator!=(double x, const Complex &y) {return x != real(y) || imag(y) != 0;
}#include <cmath>inline Complex
polar(double r, double t) {return Complex(r*cos(t), r*sin(t));
}inline Complex
conj(const Complex &x) {return Complex(real(x), -imag(x));
}inline double
norm(const Complex &x) {return real(x)*real(x) + imag(x)*imag(x);
}#endif   //__MYCOMPLEX__

侯捷的c++教程(1)相关推荐

  1. 侯捷C++系统工程师

    前言 我相信对于每一个学习C++的同学和从业者来说,台湾著名学者侯捷老师的C++系列都是不可错过的好视频. 侯捷老师在网上已有五门课,分别是:C++面向对象开发.STL标准库与泛型编程.C++新标准C ...

  2. 侯捷C++视频资源全集 | 百度网盘下载

    之前给群里的小伙伴推荐了侯捷老师, 结果他学着学着发现b站侯捷老师的视频都被下掉了. 让我想起了我当年学c++的时候在b站看候捷老师视频的那些日子,每多看一点,就会多一点恍然大悟的感觉哈哈. 辛亏我的 ...

  3. 侯捷C++八部曲笔记(五、内存管理)

    侯捷C++八部曲笔记(五.内存管理) 表达式new.delete 基本用法 array new.array delete replacement new ----------------------- ...

  4. 侯捷译Practical Java(含源码)

    侯捷译Practical Java(含源码) [url=http://www.123xz.net/soft/49/297/308/2007/20070517105923.html][B]侯捷译Prac ...

  5. 侯捷:搞Windows程序设计我们需要啥

    侯捷:搞Windows程序设计我们需要啥 如果你是一位资深的Windows程序员,相信你对Jeffrey Richter一定不会陌生,是不是有些崇拜和景仰?如果你是一位刚涉足这个领域的Windows程 ...

  6. STL体系结构与内核分析-2-STL体系结构基础介绍(侯捷)--笔记

    STL体系结构与内核分析(侯捷) 2.STL体系结构基础介绍 STL设计方式与OO(面向对象)不同的地方,OO鼓励数据和处理数据的方法都放在类里,而STL的数据在容器里,操作数据的方法在其他部件里(模 ...

  7. C++的沉迷与爱恋——侯捷

    每年的 09/28 於我都是一个特殊的日子 -- 不只是因为教师节.今年很特殊地没有普天同庆,那麽我就写篇文章自己庆祝一下好了. 我於今年七月发表了一本着作<多型与虚拟>和一本译作 < ...

  8. [转]侯捷对进入IT行业的年轻人的建议

    侯捷先生认为我们在学习技术时应该注意掌握技术的本质性.不变性和可复用性.本质的东西不易变,不易变就可复用,这三者是一体的.侯捷先生结合其个人经验告诉我们,在接触先进的技术时,如果我们能将它的底层结构 ...

  9. 侯捷面向对象高级编程(二)

    侯捷面向对象高级编程(二) 转换函数 转换函数没有返回值,返回值就是double即函数名,不需要自己写 因为转换函数一般不会改变其中内容,所以要加const限定 两条路都可以走,就回产生歧义,报错 e ...

最新文章

  1. 关于研发效能提升的思考,每个P8以及以上都应该懂!
  2. 仅需一部摄像机即可实现基于AI的3D重建
  3. Pandas选择一列或者多列数据
  4. oracle 创建数据库 表空间 用户 授权和toad导入导出数据库
  5. jquery 取对象数组下标_JQuery使用index方法获取Jquery对象数组下标的方法
  6. 保护 .NET Core 项目的敏感信息
  7. shell编程-分支语句
  8. mysql-电商库演练2-拆表-修改字段-添加外键
  9. xstatic图形连接linux,RHCE认证考试模拟题深入讲解:linux配置静态IP地址为:192.168.0.X!...
  10. 小项目也可以学习到很多东西
  11. 《逆袭进大厂》第二弹之C++进阶篇59问59答(超硬核干货)
  12. SQL语句- 条件查询
  13. 重装系统 2021年最新方法 win10纯净版本(官网方法)亲测有效
  14. Typora免费版下载【Mac、Windows】
  15. python 读取png图片 透明度
  16. 什么叫股指期货,股指期货交易流程是什么
  17. 基于JSP微信小程序汽车票订票售票系统设计与实现
  18. 真香!端午节到来,我用Python画了几个粽子送给女票,女票差点吃了我的电脑...
  19. win10安装openssl
  20. 动作捕捉技术在四足仿生机器人研究中的应用

热门文章

  1. EEPROM,NOR Flash,NAND Flash,eMMC,UFS,SSD分别和主要参数及特性
  2. 拓嘉启远:想更改拼多多主营类目,可以吗
  3. 微服务系统之认证管理
  4. String 中 split 方法的效率问题
  5. 电子商务价格分析预测
  6. Microapp 接入vite子应用
  7. Himall商城缓存类
  8. html换行(文本+符号)
  9. 点击小眼睛完成密码框的显示与隐藏睁眼和闭眼
  10. 网络安全人员需要考的几本(含金量高)的证书!