Essential C++ 笔记 - 第四章基于对象的编程风格

Essential C++ 笔记 - 第四章基于对象的编程风格

C++类的知识点
一、实现Triangular Class及对应的Triangular_Iterator Class

class Triangular_iterator {
public:
	Triangular_iterator(int index) : _index(index - 1) {}
	bool operator==(const Triangular_iterator& ) const;
	bool operator!=(const Triangular_iterator& ) const;
	int operator*() const;
	Triangular_iterator& operator++(); 		// 前置版
	Triangular_iterator& operator++(int); 	// 后置版
private:
	void check_integrity() const;

	int _index;
};

inline bool Triangular_iterator::operator==(const Triangular_iterator& rhs) const {
	return _index == rhs._index;
}

inline bool Triangular_iterator::operator!=(const Triangular_iterator& rhs) const {
	return _index != rhs._index;
}

inline bool Triangular_iterator::operator*() const {
	check_integrity();
	return Triangular::_elems[_index];
}

// 前置++:先加一,然后放入寄存器
// 后置++:先放入寄存器,后加一
inline Triangular_iterator& Triangular_iterator::operator++() {
	++_index;
	check_integrity();
	return *this;
}
inline Triangular_iterator& Triangular_iterator::operator++(int) {
	Triangular_iterator tmp = *this;
	++_index;
	check_integrity();
	return tmp;
}

inline void Triangular_iterator::check_integrity() const {
	if (_index >= Triangular::_max_elems) {
		throw exception("iterator overflow");
	}
	if (_index >= Triangular::_elems.size() ) {
		Triangular::gen_elements(_index + 1);
	}
}
class Triangular {
public:
	// 一组重载的constructors
	Triangular(); // default constructor
	Triangular(const Triangular& rhs); // copy constructor
	Triangular(int len, int begin_pos, int next);

	Triangular& operator=(const Triangular& rhs);
	void gen_elements(int length);

	// destructor
	~Triangular();

	typedef Triangular_iterator iterator;

	Triangular_iterator begin() const {
		return Triangular_iterator(_begin_pos);
	}
	
	Triangular_iterator end() const {
		return Triangular_iterator(_begin_pos+_length);
	}	

	friend int Triangular_iterator::operator*();
	friend void Triangular_iterator::check_integrity();
	
private:
	int _length;
	int _begin_pos;
	int _next;	
	static vector<int> _elems;
};

// Memberwise Initialization
Triangular::Triangular() {
	_length = 1;
	_begin_pos = 1;
	_next = 0;
}
// Member Initialization
Triangular::Triangular(int len, int begin_pos, int next) : _length(len), _begin_pos(begin_pos), _next(next) {
}

// copy constructor
Triangular::Triangular(const Triangular& rhs) : _length(rhs._length), _begin_pos(rhs._begin_pos), _next(rhs._next){

}

// copy assignment operator
Triangular& Triangular::opertor=(const Triangular& rhs) {
	_length = rhs._length;
	_begin_pos = rhs._begin_pos;
	_next = rhs._next;

	return *this;
}

void Triangular::gen_elements(int length) {
	if (length < 0 || length > _max_elems) {
		// 发送错误信息,然后return
	}
	if (_elems.size() < length) {
		int ix = _elems.size() ? _elems.size()+1 : 1;
		
		for (; ix <= length; ++ix) {
			_elems.push_back(ix*(ix+1)/2);
		}
	}
}

c++构造函数不能是虚函数:
vptr指针指向虚函数表,执行虚函数的时候,会调用vptr指针指向的虚函数的地址。
当定义一个对象的时候,首先会分配对象内存空间,然后调用构造函数来初始化对象。vptr变量是在构造函数中进行初始化的。又因为执行虚函数需要通过vptr指针来调用。如果可以定义构造函数为虚函数,那么就会陷入先有鸡还是先有蛋的循环讨论中。

基类的析构函数必须是虚函数:
BaseClass *base = new BaseClass(); 当我们执行 delete base时,会调用析构函数为我们释放资源。
BaseClass *sub = new SubClass(); 如果BaseClass基类的析构函数不是虚函数的时候,当我们执行delete sub时,只会释放BaseClass 基类申请的资源,而不是释放SubClass派生类的资源。

成员列表初始化:
Member Initialization

二、将iostream运算符重载

ostream& operator<<(ostream& os, const Triangular& rhs) {
	os << "( " << rhs._begin_pos() << ", " << rhs.length() << " )"; 
	
	return os;
}

istream& operator>>(istream& is, Triangular& rhs) {
	int bp, len;
	
	is >> bp >> len;
	
	rhs._begin_pos(bp);
	rhs._length(len);	

	return is;
}

你可能感兴趣的:(Essential C++ 笔记 - 第四章基于对象的编程风格)