作者: ayaoko
出处: http://www.cnblogs.com/fyc006/>
关于作者:小可才疏学浅还请多多赐教!
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出, 原文链接 如有问题, 可邮件(270469391@qq.com)咨询.
第一周
1.C++编程简介
1.1
我们的目标
培养正规、大气的编程习惯
1.2
1,Object Based (基于对象)
2,Object Oriented (面向对象)
1.3
C++的历史/演化(目前需要学习C11,但本课程)
C++ 1,C++语言,2,C++标准库.
语言书籍
C++ Primer 第一个编译器作者的书
The C++ PROGRAMMING LANGUAGE 之父的书
提高
Effectivc C++
标准库
The c++ standard library
stl源码剖析
1.4
c与c++区别(数据部分有没有包在一块)
1.5
类,
无指针:complex
有指针: string
2.头文件与类的声明
2.1
.h 声明
.cpp 引用#include
2.2 .h
1,<> 系统头文件
2,"" 自定义头文件
3, 防卫式的声明(防止头文件重复包含)
#ifndef __COMPLEX__
#define __COMPLEX__
#endif
4,类 前置声明,类成员函数。
5,模板简介
3.构造函数
1,内联函数 inline 比较快,比较好。试用常用简单函数。
2,public, protected, private访问级别
有public, protected, private三种继承方式,它们相应地改变了基类成员的访问属性。
1.public继承:基类public成员,protected成员,private成员的访问属性在派生类中分别变成:public, protected, private
2.protected继承:基类public成员,protected成员,private成员的访问属性在派生类中分别变成:protected, protected, private
3.private继承:基类public成员,protected成员,private成员的访问属性在派生类中分别变成:private, private, private
但无论哪种继承方式没有改变:
1.private成员只能被本类成员(类内)和友元访问,不能被派生类访问;
2.protected成员可以被派生类访问。
3,complex c1(2,3);
complex c2;
complex* p= new complex(4,4);
构造函数特有:默认参数:初值列,初始列(initialization list)
4,构造函数重载(overloading)
如果有默认值构造函数的会与类()产生歧义。
4.参数传递与返回值
1,构造函数 private (设计模式:Singleton )。
static
2,const函数(不会修改数据内容的增加const)
const类实例化对象:下面情况看,函数需要加。
const complex c1(2,1)
cout<<c1.real();(double real() CONST{return re;}
3,参数传递:pass by value vs pass by reference(to const)
建议出入参建议使用 引用。
const 引用(指针)保护修改。
4,友元friend
自由取得friend的private成员。
5,相同class的各个objects互为friends(友元)
int func(const complex& param)
{return param.re + param.im}
6,首先返回引用
return by reference;
5.操作符重载与临时对象
1,操作符重载.
1.1成员函数,带有隐藏函数入参this(不必写也不能写).
1.2return by reference(c3+=c2+=c1)
传递着无需知道接收者是以reference 形式接收。
1.3非成员函数,operator+因为左右并没有存在绝对不能return by reference,
它们返回的必定就个local object 。temp object(临时对象) typename();
1.4临时对象如 负(-),不能return reference.
1.5 绝对不要把<<写成员数,要写全局函数(无法识别新的类型)。
ostream& 不能加 const
1.6 cout<<c1<<conj(c1);(不好<<return void)
总结:
构造函数 initialization list
需要考虑 const
尽量考虑 reference
数据尽量 private
6.复习Complex类的实现过程
7.实例(Complex)代码
.h
#ifndef __MYCOMPLEX__
#define __MYCOMPLEX__
#include <cmath>
#include <iostream>
using namespace std;
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:
complex (double r = 0, double i = 0): re (r), im (i) { }
complex& operator += (const complex&);
complex& operator -= (const complex&);
complex& operator *= (const complex&);
complex& operator /= (const complex&);
double real () const { return re; }
double imag () const { return im; }
private:
double re, im;
friend complex& __doapl (complex *, const complex&);
friend complex& __doami (complex *, const complex&);
friend complex& __doaml (complex *, const complex&);
};
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.imag ();
}
inline double
real (const complex& x)
{
return x.real ();
}
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;
}
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__
.cpp
#include "complex.h"
ostream&
operator << (ostream& os, const complex& x)
{
return os << '(' << real (x) << ',' << imag (x) << ')';
}
int main()
{
complex c0(1, 2);
complex c1(2, 1);
complex c2(4, 0);
cout << c0 << endl;
cout << c1 << endl;
cout << c2 << endl;
cout << c1+c2 << endl;
cout << c1-c2 << endl;
cout << c1*c2 << endl;
cout << c1 / 2 << endl;
cout << conj(c1) << endl;
cout << norm(c1) << endl;
cout << polar(10,4) << endl;
cout << (c1 += c2) << endl;
cout << (c1 == c2) << endl;
cout << (c1 != c2) << endl;
cout << +c2 << endl;
cout << -c2 << endl;
cout << (c2 - 2) << endl;
cout << (5 + c2) << endl;
return 0;
}
8.作业
题目:
为Date类实现如下成员:
构造器,可以初始化年、月、日。
大于、小于、等于(> 、< 、==)操作符重载,进行日期比较。
print() 打印出类似 2015-10-1 这样的格式。
然后创建两个全局函数:
第1个函数 CreatePoints生成10个随机的Date,并以数组形式返回;
第2个函数 Sort 对第1个函数CreatePoints生成的结果,将其按照从小到大进行排序。
最后在main函数中调用CreatePoints,并调用print将结果打印出来。然后调用Sort函数对前面结果处理后,并再次调用print将结果打印出来。
class Date
{
int year;
int month;
int day;
};
答案:没有唯一,各自乐趣去写。
9.扩展
Folly Facebook开源代码库
csapp 深入理解计算机系统
scip 计算机程序的构造和解释
clrs 算法导论
apue UNIX环境高级编程
在线问题:
申请一个栈空间,里面放上堆内容(或指针指到堆上)
答案:
友元的声明
友元的声明仅仅指定了访问的权限,而非一个通常意义上的函数声明。如果我们希望
类的用户能够调用某个友元函数,那么我们就必须在友元声明之外再专门对函数进行一次声明。
为了使友元对类的用户可以,我们通常把友元的声明与类本身放置在同一个头文件中(类的外部)。
因此,我们的sale_data头文件应该为read、print和add提供独立的声明(除了类内部的友元声明之外)。
许多编译器并未强制限定友元函数必须在使用之前在类的外部声明.
一些编译器允许在尚无友元函数的初始声明的情况下就调用它。不过即使你的编译器
支持这种行为,最好还是提供一个独立的函数声明。这样即使你更换了一个有这种强制要
求的编译器,也不必改变代码。