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

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

#include <iostream>
#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 <cstring>   // 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 <iostream>
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";
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值