很简单 -> 写个复数的class咯,注意些基本细节
#ifndef INC_2_9_COMPLEX_H
#define INC_2_9_COMPLEX_H
class complex {
public:
complex(double r = 0, double i = 0)
: re(r), im(i) {}
complex &operator+=(const complex &);
double real() const { return re; }
double imag() const { return im; }
private:
double re, im;
friend complex &__doapl(complex *, const complex &);
};
inline complex &
__doapl(complex *ths, const complex &r) // 他们是什么类型呢, this是指针类型,另一个是complex类型
{
ths->re += r.re;
ths->im += r.im;
return *ths; // 指针所指的对象,传出去,外面怎么接收可以不用管,可以by value, by reference
}
// 这个操作符是作用再左边的,成员函数有个隐藏的参数this
// 如果里面不是 local object,不是临时创建出来的对象的,那就返回引用, 这里是右边对象加到左边对象
inline complex & // 接口的部分
complex::operator+=(const complex &r) {
// 定义部分
return __doapl(this, r);
}
inline double
imag(const complex &x) {
return x.imag(); // 这是通过这个obj的func调用的啊,ok的,并不是x.re
}
inline double
real(const complex &x) {
return x.real();
}
//inline complex
//operator + (const complex& x)
//{
// return x;
//}
//inline complex
//operator - (const complex& x)
//{
// return {-real(x), -imag(x)};
//
//}
// 这里是考虑到 复数 + 复数
inline complex
operator+(const complex &x, const complex &y) // 这里设计为全局函数,已经没有类的名称前面了 // 不会改变 注意 const,同时注意传引用
{
// 创建对象的语法, 类的名称后面加上括号 也是创建, 初始值就是括号里面传递的
return complex(real(x) + real(y), imag(x) + imag(y)); // 新的对象用来存放,local,注意返回的时候一定不能by reference,一定是by value
}
// 然后也考虑到 复数 + 实数
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));
}
// 操作符重载一定是作用在左边这个数,可以写成2中,成员函数或者非成员函数
ostream & // 传回的是引用吗,考虑到后续的用法哦
operator<<(ostream& os, const complex& x) { //细品,右边丢到左边去,右边就const,又因为cout状态会改变,连续的那种 << << 不加const
return os << '(' << real(x) << ',' << imag(x) << ')';
}
#endif //INC_2_9_COMPLEX_H
闲着也是闲着,那再来个 String class
#ifndef INC_2_9_STRING_H
#define INC_2_9_STRING_H
class String
{
public:
String(const char* cstr = 0);
// big three
String (const String& str); // 拷贝构造
String& operator = (const String& str); //返回的要不要加引用呢,函数执行完结果是不是local object,如果不是,当然优先引用
~String(); // 析构
char* get_c_str() const {return m_data;}
private:
// 32位电脑中,一个指针是4个byte
char* m_data; // 因为字符串 有长短,不能设定一个长度,用个指针就ok,将来利用这个指针动态分配大小
};
inline
String:String (const char* cstr=0) // 构造函数
{
if (cstr){
m_data = new char[strlen(cstr) + 1]; // new 空间
strcpy(m_data, cstr); // 拷贝进来, 用了c的 strcpy 记得include
}
else{
m_data = new char[1];
*m_data = '\0';
}
};
inline
String::~String()
{
delete[] m_data; // 释放内存空间
}
inline
String::String(const String& str) // 拷贝构造, s2(s1)
{
m_data = new char[strlen(cstr) + 1];
strcpy(m_data, str.m_data);
}
inline
String& String::operator=(const String &str) // 拷贝赋值 s3 = s1, s3本来有东西的
{
// 上面的 &在typename后面是 引用
// 这里是 &取地址 放在object的前面
if (this == &str) // 判定自我赋值情况!
return *this
delete [] m_data;
m_data = new char[strlen(str) + 1];
strcpy(m_data, str.m_data);
// 传出去的人return, 不需要知道外部怎么去接收,外面可以 by value 或者 by reference
return *this; // 记得return 这个目的段指针指向的内存块, 连串的赋值情况 s1 = s2 = s3, 返回类型为 String&
}
#endif //INC_2_9_STRING_H