c++ - a sample class to show common aspects of object initialization/uninit

The following classes show many a apsect of object life-cycle management, including the single argument constructor, copy constructor, default constructor, expclit constructor,  destructor and the non-static member and static member, and how to define/impl those classes

 

We might use the definition on this chapter later for other illustration. 

 

/**
* file
*  acct.h
* description: 
*   the class definition of the Account class
*
*/
class Account {

public:

/* =================
* ctor and dtors
========================*/
	Account();
	// since a constructor that takes only a single parameter can serves as a conversion operator
	// we don't want tripwire people into the trap of 
	//  Account acct = "new user";
	// to help curb/reign this kind of unwantted/unwelcome compiler aid, the explicit keyword is introduced 
	//  
	explicit
	Account(const char *, double = 0.0);
	
	//// for the purpose of demo the use of the array initalizer, we decide to use the implicit constructor approach
	//Account(const char *, double = 0.0);

	// the copy constructor 
	// the most important thing about the copy constructor is to decide whether or not to provide the copy constructor
	// the how as to implements the copy constructor comes seconds
	Account(const Account & );
	~Account();
	const char * name();

private:
	char * _name;
	unsigned int _acct_nmbr;
	double _balance;
	
	static unsigned int _unique_acct_nmbr;
	static unsigned int get_unique_acct_nmbr();
	static void return_acct_nmbr(unsigned int acct_nmbr);
protected:
};

 

 

and below is the definition/implementatio of the classes..

 

/**
* file 
*   acct.cpp
* description: 
*   the implementation source file of the acct.h
*/


#include "stdafx.h"
#include "acct.h"
#include <iostream>
#include <typeinfo>
#include <exception>
#include <fstream>
#include <functional>
#include <algorithm>
#include <vector>
#include <list>
#include <array>
#include <iterator>
#include <cstring>
#include <memory>

using std::cout;
using std::endl;
using std::end;
using std::cerr;
using std::fstream;
using std::vector;
using std::list;

using std::strcpy;
using std::strcat;
using std::strlen;

using std::auto_ptr;


/*=================================
* ctor(s) and dtor(s)
==================================*/

// for non-class members, it does not matter if you initialize the non-class member in the initializer list of you initialize the 
// the non-class member inside the constructor's body
// the convention is to initialize the non-class members inside the ctor's body, while initialize the class members in the initializer's initializer list
Account::Account() {
	_balance = 0.0;
	_name = 0;
	_acct_nmbr = 0;
	_acct_nmbr = get_unique_acct_nmbr();

	cout << "Account::Account" << endl;
}

// As said before,you can initialize the non-class member in the initliazer list. 
//Account::Account() :
//   _balance (0.0), _name(0), _acct_nmber(0)
//{
//}

// though the declaration of the Account is as such
// Account(const char * naem_, double balance_ = 0.0);
// but in our discussion, we can NOT redefine the default value of the balance_
Account::Account(const char * name_, double balance_) {
	cout << "Account::Account(const char * name_, double balance_)" << endl;

	if (name_ != NULL) {
		// thereis no need to call the delete operator because 
		// in the intializer, the name_ is guaranteed to be filled with som randome bitness
		// while the static members will be filled with zero or its default values (normally it is zeros)
		//delete name_;
		_name = new char[strlen(name_) + 1];
		strcpy(_name, name_);
	}
	_balance = balance_;

	_acct_nmbr = get_unique_acct_nmbr();
}

Account::Account(const Account& rhs) 
	: _balance(rhs._balance)
{
	cout << "Account::Account(const Account & rhs)" << endl;
	_name = new char[strlen(rhs._name) + 1];
	strcpy(_name, rhs._name);

	// must copy rhs._acct_nmbr
	_acct_nmbr = get_unique_acct_nmbr();
}

unsigned int 
	Account::_unique_acct_nmbr;

unsigned int
Account::get_unique_acct_nmbr() { 

	return ++_unique_acct_nmbr;
}

void 
	Account::return_acct_nmbr(unsigned int acct_nmbr) { 

}

inline
const char *
	Account::name() {
		return _name;
}

// Destructor server primarily to relinquish resources acquired either within the constructor or urnig the lifetime 
// thelifetime of the class object, again such as freeing a mutal exclsion lock or deleting memory allocated through operator new.
Account::~Account()  
{
	delete _name;
	return_acct_nmbr(_acct_nmbr);

	// there is no need to do the check 
	// because the compiler will ensure that. 
	//if (_name != NULL ) delete _name;
	// and since the object is destructed, there is no need to rest to some uninitialized value.
	//_name = 0;
	//_balance = 0;
	//_acct_nmbr = 0;
}

Account global;

void destructor_life_cycle_test()
{
	Account local("Anna live Plurablle", 1000);
	Account &loc_ref = global;
	auto_ptr<Account> pact(new Account("stephen Dedalus"));

	{
		Account local_too("Stephen Hero");
		// the local_too will destroy before exit the current local space. 
	}
	// the auto_ptr will destruct here

}
 

你可能感兴趣的:(C++)