C++ 面向对象笔记——侯捷老师(一)

C++ 面向对象笔记——侯捷老师(一),第1张

此笔记为侯捷老师的C++面向对象课程笔记,在开篇中,老师首先讲C++的类,并将类分为两种基本类型:

1、类的成员不带指针的类。

以复数类为例,讲解类的基本知识。

  1. 类的基本构成:成员变量和成员函数。

    构造函数和析构函数的基本语法。

    重点是使用初始化列表对类的成员赋初始值的方法。

  2. public、private、protected三种access的差别,friend右元的作用。

  3. 重点讲了reference(&)的使用,传值和传引用的区别。

  4. 在构建类时创建函数的基本思想:函数什么时候作为类的成员函数,什么时候该使用全局函数。

  5. 内联的作用:类里面定义的函数自动视为内联,类外面的函数尽可能使用内联。

  6. *** 作符重载。

2、类的成员带指针的类。

以string类为例。

  1. 主要讲解三大函数:拷贝构造函数、拷贝赋值函数、析构函数。

  2. 带指针的类必须有拷贝构造函数和拷贝赋值函数。

    因为编译器默认的拷贝是逐个bit的拷贝,两个类中都是指针,编译器默认的拷贝执行之后,会变成两个指针指向同一块内存,源指针可能造成内存泄漏。

  3. complex类中没有指针,不需要析构,离开作用域时类就消失了。

    而带指针的函数需要析构。

    由于构造函数中有动态分配内存(new),析构函数中配合使用delete。

    指针为数组指针时,使用delete[ ];

  4. 同类的不同对象视为彼此friend,可以访问私有成员变量。

  5. 赋值动作三步:杀掉自己(delete),分配一块内存给自己(new),拷贝数据(strcpy)。

  6. 拷贝赋值函数中首先检测自我赋值,为什么内,一是为了提高效率,而是防止可能产生的错误,两个对象本来就指向同一块内存,这时候进行拷贝赋值 *** 作,首先会清掉自己的内存,就直接清掉了两个对象中的数据,无法再执行拷贝 *** 作。

  7. stack(栈)和heap(堆)。

    stack是存在于某作用域(scope)的一块内存空间,调用函数时,函数本身会形成一个stack用来防止所接收的参数以及返回地址。

    函数本体内声明的任何变量,所使用的内存块都取自stack。

    heap是 *** 作系统提供的一块global内存空间,程序可通过动态分配从其中获得一些内存区块(block)。

  8. new一个对象的时候,先分配内存(malloc)返回一个void指针,第二步将void指针转换为类的指针,第三步调用构造函数,初始化对象。

  9. delete一个对象的时候,先调用析构函数,再释放内存(free)。

设计复数类:

#ifndef _COMPLEX_
#define	_COMPLEX_
#include	

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; }
	~complex();

private:
	double	re, im;
	friend	complex& _doap1(complex*, const complex&);
};

inline	complex&
_doap1(complex* ths, const complex& r)
{
	ths->re += r.re;
	ths->im += r.im;
	return *ths;
}

inline	complex&
complex:: operator+= (const complex& r)
{
	return	_doap1(this, r);
}

complex::~complex()
{
}

/*复数类可能参与复数与实数的运算,所以是全局函数*/
inline	complex
operator+ (const complex& x, const complex& y)
{
	return complex (x.real() + y.real(),
		x.imag() + y.imag()
	);
}

inline	complex
operator+ (const complex& x, double	y)
{
	return complex(x.real() + y,
		x.imag()
	);
}

inline	complex
operator+ (double	x, const complex& y)
{
	return complex(x + y.real(),
		y.imag()
	);
}

inline std::ostream&
operator<< (std::ostream& os, const complex& x)
{
	os << x.real() << "+" << x.imag();
	return os;
}
#endif // !_COMPLEX_

测试complex类: 

#include     
#include    "myComplex.h"

int main()
{
    complex test1(2, 3);
    complex test2(3, 4);

    std::cout<< test1+test2 <

设计String类:

#ifndef _MY_STRING_H_
#define	_MY_STRING_H_
#include	
#include	
using namespace std;
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; }

private:
	char* m_data;
protected:
};


inline
String::String(const char* cstr)
{
	if (cstr)
	{
		m_data = new char[strlen(cstr) + 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&
String::operator = (const String& str)
{
	if (this == &str)
		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;
}

std::ostream& operator << (ostream & os, const String& str)
{
	os << str.get_c_str();
	return os;
}
#endif // !_MY_STRING_H_

测试String类:

#include 
#include    "MyString.h"
using namespace std;

int main()
{
    String  s1;
    String  s2("hello");
    String  s3(s2);
    s1 = s3;
    cout << s1 << endl;
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/674032.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-19
下一篇 2022-04-19

发表评论

登录后才能评论

评论列表(0条)