c++学习笔记(1):《侯捷C++面向对象高级开发》学习笔记

阅读于侯捷《C++面向对象高级开发》

太细节,没基础不要看,有一些我也看不懂

一、

complex.h:

#ifndef __COMPLEX__
#define __COMPLEX__
//防卫式函数声明

calss complex
{
public:
	complex(double r=0,double i=0):re(r),im(i){}
	complex& operator +=(const complex&);
	double real()const {return rm;}
	double imag()const {return im;}
private:
	double re,im;
	friend complex& __doapl(complex* const complex&); //友元函数
}
#endif





    

complex.cpp:

inline complex& __doapl(complex* ths,const complex& r) //由于第一个形参要改变,不能加const,第二个不变,可以加const
{
	ths->re += r.re;
	ths->im +=r.im;
	return *ths;
}

inline complex& complex::operator += (const complex& r)  //如果return非函数内新建的,不是local,则可以返回引用
{
	return __doapl(this,r);
}

inline complex operator + (const complex& x,const complex& y) //只能return 值,不能return reference
{
	return complex(real(x)+real(y),imag(X)+imag(y)); //直接类名加初值,相当于新建一个类,在初始化。是一个临时对象
}


#include<iostream.h>
//重载<<操作符
ostream& operator <<(ostream & os,const complex& x)  //输出流重载操作符:只能是非成员函数
{
    return os<<'('<<real(x)<<','<<imag(x)<<')';
}


pass/return by value 传值

pass/return by reference 传引用

二、三大函数:拷贝构造,拷贝赋值,析构

Class with pointer member 必须有 copy ctor 和 copy op=(拷贝构造,拷贝赋值)

string.h

#ifndef __MYSTRING__
#define __MYSTRING__

class String
{
public:
	String(const char* cstr = 0);
    String(const String& str);  //拷贝构造
    String& operator=(const String& str); //拷贝赋值
    ~String();  //析构
    char* get_c_str() const{return m_data;}  //不改变值,加const
private:
    char* m_data;
}

inline String::String(const char* cstr = 0)  //使用举例:String s2("hello");String s1();
{
	if(cstr){
        m_data = new char[strlen(cstr)+1];  //根据传进来的字符长度+1,创建新内存
        strcpy(m_data,cstr);
    }
    else{ //未指定初值
        m_data = new char[1];
        *m_data = '\0';
    }
}
inline String::String(const String& str){
    m_data = new char[strlen(str.m_data)+1];
    strcpy(m_data,str.m_data);
}
inline String::operator=(const String& str)  //String s1("hello");String s2(s1);s2=s1
{    
  	if(this == &str)  //检测自我赋值(self assignment)
       	return *this;
  	delete[] m_data;   //清空内存
  	m_data = new char[strlen(str.m_data)+1]; //新建内存
    strcpy(m_data,str.m_data);  //赋值
    return *this;
}
inline String::~String(){
    delete[] m_data;
}

#include<iostream.h>
ostream& operator<<(ostream& os,const String str)
{
    os<<str.get_c_str();
    return os;
}


#endif
String s1("helllo ");
String s2(s1); //等价于 String s2=s1; 

三、堆,栈,内存管理

Stack 存在于某作用域(scope)的一块内存空间(自动释放)

Heap 由操作系统提供的一块global内存空间 ,程序可动态分配(需要手动delete)

stack objects生命期:auto object 离开作用域自动释放

static object 其生命在作用域结束之后仍然存在,知道整个程序结束

global object 其生命在整个程序结束之后,才结束。

new char[*] delete[] * array new 搭配 array delete

String* p=new String[3];

delete [] p; //唤起3次dtor(析构函数)
//
delete p;  //唤起1次dtor(析构函数) ??? 

//如果没有指针,delete [] p 和 delete p 一样

四、类模板、函数模板及其他

static data members    //多个实例用同一个内存

static member functions  //
    
    
class Account{
public:
	static double m_rate;
	static void set_rate(cosnt double& x){m_rate=x;}
};
double Account::m_rate = 8.0;
int main(){
    Account::set_rate(5.0);
    Account a;
    a.set_rate(7.0);    
    //调用static函数的方法:1、通过object调用;2、通过class name 调用
}
    
    

ctors放在private

class A{
public:
	static A& get Instance(return a;);
	setup() { }
private:
	A();
	A(const A& rhs);
	static A a;    //没有人使用,a也存在,浪费内存
}


A::getInstance().setup(); //设计模式


//2、
class A{
public:
	static A& get Instance();
	setup() { }
private:
	A();
	A(const A& rhs);

}
	
A& A::getInstance(){  //只有人使用时,a才存在
   	static A a;
    return a;
}
A::getInstance().setup(); //设计模式
类模板
template<typename T>
class complex{
public:
	complex(T r=0,T i=0):re(r),im(i){}
    T real()const {return rm;}
	T imag()const {return im;}
private:
	T re,im;
	friend complex& __doapl(complex* const complex&); //友元函数
}
int main()
{
complex<double> c1(2.5,1.5);
complex<int> c2(2,6);
}
function template
template <class T>
inline const T& min(const T& a,const T& b){
    return b<a ? b:a;
}

stone r1(2,3),r2(3,3),r3;
r3 = min(r1,r2 )
namespace
namespace std
{
	//....
}
using dirctive
#include<iostream.h>
using namespace std;
int main(){
    cin>>....;
    cout<<endl;
}
using declaration
#include<iostream.h>
using std::cout;
int main(){
    std::cin>>....;
    cout<<std::endl;
}
//or
#include<iostream.h>
int main(){
    std::cin>>....;
    std::cout<<std::endl;
}

五、组合与继承

Inheritance 继承 is-a

Base //base class 的 析构函数必须是virtual
Derived

//构造由内而外: Derived的构造函数先调用Base的deagult构造函数,然后才执行自己
//析构由外而内: Derived的析构函数先执行自己,然后才调用Base的deagult析构函数
class Derived:public Base{//,,,};

Composition复合 has-a

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mU77EC9b-1594823376168)(C:\Users\jiame\AppData\Roaming\Typora\typora-user-images\1594443587123.png)]

template <class T>
class queue{
protected:
    deque<T> c;
public:
    //利用c的操作函数完成
    bool empty() const { return c.empty();}
    size_type size() const { return c.size();}
	//。。。
}

Container<<**>>--->component
Contaniner object{Component part}
//构造由内而外: Container的构造函数先调用Component的deagult构造函数,然后才执行自己
//析构由外而内: Container的析构函数先执行自己,然后才调用Component的deagult析构函数

Delegation 委托 Composition by reference
//file String.hpp
class StringRep;
class String
{
public:
	String(const char* cstr = 0);
    String(const String& str);  //拷贝构造
    String& operator=(const String& str); //拷贝赋值
    ~String();  //析构
    char* get_c_str() const{return m_data;}  //不改变值,加const
private:
    StringRep* rep; //Handle Body
};
//file String.cpp
class StringRep{
friend class String{
	//....
};

六、虚函数与多态

virtual

non-virtual ,不希望derived class重新定义(override,覆写)它,

virtual函数,希望derived class重新定义(override,覆写)它,而且它已经有默认定义

pure virtual函数,希望derived class重新定义(override,覆写)它,而且它没有默认定义

通过子类的对象调用父类的函数时,若该函数在子类中有override,则执行子类的函数定义

(Template Method 设计模式之一 )

Inheritance+Composition 关系下的构造和析构

七、委托相关设计

。。。。。。(暂时阵亡)

八、导读

1、conversion function 转换函数

class Fraction
{
public:
    Fraction(int num,int den=1):m_numerator(num),m_denominator(den){}
	operator double() const{  //返回类型默认double
        return (double)m_numerator/(double)m_denominator;
    }        
private:
    int m_numerator;
    int m_denominator;
Fraction f(3,5);
double d=4+f //调用operator double()将f转成double类型 :0.6

2、non-explicit-one-argument ctor

class Fraction
{
public:
   Fraction(int num,int den=1):m_numerator(num),m_denominator(den){}
   Fraction operator +(const Fraction& f) {
       return Fraction(....);
   }        
private:
   int m_numerator;
   int m_denominator;
Fraction f(3,5);
Fraction d=4+f //调用non-explicit ctor将4转成Fraction,然后调用operator+

3、explicit-one-argument ctor

class Fraction
{
public:
   explicit Fraction(int num,int den=1):m_numerator(num),m_denominator(den){}
   									//若不加explict,下面两个函数有二义性
   Fraction operator +(const Fraction& f) {
       return Fraction(....);
   operator double() const{  //返回类型默认double
       return (double)m_numerator/(double)m_denominator;
   }        
private:
   int m_numerator;
   int m_denominator;
Fraction f(3,5);
Fraction d=f+4 //

4、Pointer-like classes

关于智能指针

template<class T>
class shared_ptr
{
public:
    T& operator*()const{
        return *pt;
    }
    T* operator->()const{
		return px;
    }
    shared_ptr(T* p):px(p){}
private:
    T* px;
   	long* pn;
}
shared_ptr<Foo> sp(new Foo);
Foo (*sp); //指针能用的操作符,这个都能用
sp->method(); //== px->method();

迭代器

5、function-like classes

仿函数

像函数的对象

6、 namespace

namespace jj01
{
    
}
namespace jj02
{
    
}
int main(int argc,char** argv)
{
    jj01::test();
    jj02::test();
    return 0;
}
    

7 、class template

8、function template

。。。

9、member template

template <class T1,class T2>
struct pair{
	typedef T1 first_type;
	typedef T2 second_type;
	T1 first;
	T2 second;
	pair():first(T1()),second(T2()){}
	pair(const T1& a,const T2& b):first(T1),second(T2){}
	
	template<class U1,class U2> //成员又是一个模板(无情套娃)
	pair(const pair<U1,U2>& p):first(p.first),second(p.second){}
}

10、specialization

特化 (反义:泛化)

template <class Key> //泛化
struct hash{};

template<> 
struct hash<char>{  //特化
	size_t operator()(char x) const {return x;}
}
template<>
struct hash<int>{
	size_t operator()(int x) const {return x;}
}
template<>
struct hash<long>{
	size_t operator()(long x) const {return x;}
}

cout<<hash<long>()(1000);

11、parital specialization

模板偏特化–个数的偏

template<typename T,typename ALloc=...>
class Vector{
...
};
//T-->bool,后面的默认,称之为个数的偏,只能从左到右
template<tpename Alloc=...>
class vector<bool,Alloc>
{
...
};

范围的偏 :比如任意类型 --特化>必须指针类型

template<typename T>
class C{
...
};

template<typename T>
class C<T*>{
...
};

//
C<string> obbj1;
C<string*> obj2;

12、template template parameter

模板模板参数(又套娃???)

template<typename T,template<typename T>class Container>
class XCls{
private:
	Container<T> c;
public:
	//...
};

//use
template<typename T>
using Lst = list<T,allocator<T>>; 


XCls<string,list> mylst1;
XCls<string,Lst> mylst2;

13、C++标准库

STL。。。。

cout<<__cpluscplus<<endl;//查看cpp编译器版本

14、variadic templates、auto、range-base for (C++ 11语法糖)

ariadic templates

数量不定的模板参数pack

template<typename T,typename... Types> //'...'代表不定数量的参数
void print(const T& firstArg,const Types&... args)
{
    cout<<firstArg<<endl;//sizeof...(args) 返回 args...一包的参数数量
    print(args...); //递归调用,至少有一个参数,另写一个函数兼容,参数依次减少
}
void print(){
}

auto 自动选择返回类型

list<string> c;
....
auto ite = find(c.begin(),c.end(),target);

range-base for

for(int i: {2,3,4,5}){
    cout<< i <<endl;
}

vector<double> vec;
....
for(auto elem : vec){ //pass by value
	cout<<elem<<endl; //若elem *= 3,不会改变vec中的值
}
for(auto& elem : vec){ //pass by reference
    elem *= 3; //因为pass by reference,会改变vec中的值
}

15、Reference

int x=0;
int* p = &x; //p is a poniter to x
int& r = x; //r is a reference to x;r代表x,r,x都是0
int x2 = 5;

//注意:sizeof(r) == sizeof(r),  &x == &r  object和其reference的大小,地址都相同(假象)

r = x2; // r不能重新代表其他物体,r,x现在都是5;
int& r2 =r;  现在r2 是5(r2 代表 r:亦相当于代表x(又又又套娃??)
double imag(const double& im) {}
double imag(const double  im) {}
//"same signature"二者不能同时存在
//“imag(const double  im) {}” :signature

16、Inheritance+Composition 关系下的构造和析构

base

|

Derived --> Component

**构造由内而外:**Derived的构造函数先调用Base的deagult构造函数,然后调用Component的default构造函数,然后才执行自己
**析构由外而内:**与构造相反。。

17、vptr、vtbl

虚指针、。。。。。(看不懂)

18、this

略过

19、Dynamic Binding

A<-B<-C

B b;
A a = (A)b;
a.vfuncl();  //静态绑定

A* pa = new B; //动态绑定
pa->vfuncl();

pa = &b;  
pa->vfuncl();

20、const

当常成员的const和non-const版本同时存在,

const object 只会调用const版本

non-const object 只会调用non-const版本。

​ const object non-const object

const member functions Y Y

non-const member functions N Y

21、Operator new、Operator delete

global:


inline Void* operator new(size_t size){
    return myAlloc(size);
}
inline void* operator new[](size_t size){
    return myAlloc(size);
}

member operator new/delete

此处不详细,另寻他家吧。。。

17、vptr、vtbl

虚指针、。。。。。(看不懂)

18、this

略过

19、Dynamic Binding

A<-B<-C

B b;
A a = (A)b;
a.vfuncl();  //静态绑定

A* pa = new B; //动态绑定
pa->vfuncl();

pa = &b;  
pa->vfuncl();

20、const

当常成员的const和non-const版本同时存在,

const object 只会调用const版本

non-const object 只会调用non-const版本。

​ const object non-const object

const member functions Y Y

non-const member functions N Y

21、Operator new、Operator delete

global:


inline Void* operator new(size_t size){
    return myAlloc(size);
}
inline void* operator new[](size_t size){
    return myAlloc(size);
}

member operator new/delete

此处不详细,另寻他家吧。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值