Primer plus C++ 第十一章 类和动态内存分配_反面理解String类(class and dynamic memory allocation)

/************************************************************************/
/* 
strngbad.h __ flawed(缺点) string class definition
*/
/************************************************************************/

#include 
#ifndef STRNGBAD_H_
#define STRNGBAD_H_

class StringBad
{
private:
	char * str;  // pointer to string
	int len;     // length of string
	static int num_strings;
public:
	StringBad (const char * s);  // constructor
	StringBad();    // default constructor
	~StringBad();   // destructor
	// friend function
	friend std::ostream & operator << 
		(std::ostream & os, const StringBad & st);
};

#endif
/*
Notes:
	1)you cannot initalize a static member variable inside the class declaration.
	That's becase the declaration is a description of how memory is to be allocated 
	but it doesn't allocate memory.
	2)In the case of a static class member, you initialize the static member independently,
	with a separate state-ment outside the class declaration. That's because the staic class 
	member is stored separately tather than as part of an object.
	3)This initializetion goes in the methods file, not in the class declaration file.
		That would result in multiple copies of the initialization statement, which is an 
		error.
*/
// strngbad.cpp -- StringBad class methods

#include    // string.h for some
#include "strngbad.h"

using std::cout;

// initializing static class member
int StringBad::num_strings = 0;

// class methods
// construct StringBad from C string
StringBad::StringBad(const char * s)
{
	len = std::strlen(s);   // set size
	str = new char[len + 1];   // allot storage
	std::strcpy(str, s);   // initialize pointer
	num_strings++;   // set object count
	cout << num_strings << ": \"" << str
		<< "\" object created \n ";   // For Your Information

}

StringBad::StringBad()   // default constructor
{
	len = 4;
	str = new char[4];
	std::strcpy(str, "c++");   // default string
	num_strings++;
	cout << num_strings << ":\" "<< str
		<< "\" default object created\n";  // FYI
}

StringBad::~StringBad()  // necessary destructor
{
	cout << "\" "<< str << "\" object deleted, ";
	-- num_strings;  // required
	cout << num_strings << " left \n";
	delete [] str;  // required
}

std::ostream & operator << (std::ostream & os, const StringBad & st)
{
	os << st.str;
	return os;
}
/************************************************************************/
/* 
1、vegnews.cpp -- using new and delete with classes
2、remember:
	The problems with the StringBad class stem from implicit member functions that are
	defined automatically and whose behavior is inappropriate to this particular class design.
	stem [stem] n. 干;
	automatically [,ɔ:tə'mætikəli] adv. 自动地;机械地;无意识地
	behavior [bi'heivjə] n. 行为,举止;态度;反应
	inappropriate [,inə'prəupriət] adj. 不适当的;不相称的
	particular [pə'tikjulə] adj. 特别的;详细的;独有的;挑剔的
3、C++  automatically provides the following memeber functions:
	1)A default constructor if you define no constructors
	2)A copy constructor if you don't define one
	3)An assignment operator if you don't define one ( 赋值操作符)
	assignment [ə'sainmənt] n. 分配;任务;作业;功课
	operator ['ɔpəreitə] n. 经营者;操作员;话务员;行家
	4)A default destructor if you don't define one
	5)An address operator if you don't define one(地址操作符)
*/
/************************************************************************/

#include 
using std::cout;
#include "strngbad.h"

void callme1(StringBad &);  // pass by reference(按引用传递)
void callme2(StringBad);    // pass by value(按值传递)

int main()
{
	using std::endl;
	// create three StringBad objects
	StringBad headline1("Celery Stalks at Midnight");
	StringBad headline2("Lettuce Prey");
	StringBad sports("Spinach Leaves Bowl for Dollars");

	cout << "headlines1: " << headline1 << endl;
	cout << "headlines2: " << headline2 << endl;

	cout << "sports: " << sports << endl;
	// passes handline1 to the callme1()function
	callme1(headline1);

	cout << "headlines1: " << headline1 << endl;
	callme2(headline2);
		cout << "headlines2: " << headline2 << endl;
		cout << "Initialize one object to another: \n";
		StringBad sailor = sports;
		cout << "sailor: " << sailor << endl;
		cout << "Assign one object to another: \n";
		StringBad knot;
		knot = headline1;
		cout << "knot: " << knot << endl;
		cout << "End of main() \n";
		return 0;
}

void callme1(StringBad & rsb)
{
	cout << "String passed by reference: \n";
	cout << " \" "<< rsb << "\"\n";
}

void callme2(StringBad sb)
{
	cout << "String passed by value: \n";
	cout << " \" "<< sb << "\"\n";
}

你可能感兴趣的:(C++语言学习,c++)