首页 > 系统相关 >61.动态内存和类

61.动态内存和类

时间:2023-03-09 22:56:37浏览次数:35  
标签:std 初始化 静态 StringBad char 61 动态内存 strngbad

程序清单12.1 strngbad.h

#pragma once
//strngbad.h -- 有缺陷的string类定义
#include <iostream>
#ifndef STRNGBAD_H_
#define STRNGBAD_H_
class StringBad
{
private:
	char * str;//指向字符串的指针
	int len;//字符串长度
	static int num_strings;//对象数量
public:
	StringBad(const char* s);//构造函数
	StringBad();//默认构造函数
	~StringBad();//默认的析构函数
	//友元函数
	friend std::ostream & operator << (std::ostream & os, const StringBad & st);
};
#endif

  StringBad这个类时使用动态内存分配来开发类的第一个阶段,正确地完成了一些显而易见的工作,例如,在构造函数和析构函数中正确地使用了new和delete。这个类没什么错误,但忽略了一些不明显却不可少的东西。

  对这个声明,需要注意的有两点。首先,它使用char指针(而不是char数组)来表示姓名。这意味着类声明没有为字符串本身分配存储空间,而是在构造函数中使用new来为字符串分配空间。这避免了在类声明中预先定义字符串的长度。

  其次,将num_strings成员声明为静态存储类。静态存储成员有一个特点:无论创建了多少对象,程序都只创建一个静态类变量副本。也就是说,类的所有对象共享同一个静态成员。

程序清单12.2 strngbad.cpp

#pragma warning(disable:4996)
#define _CRT_SECURE_NO_WARNINGS 1

//strngbad.cpp -- StringBad类方法
#include <cstring>
#include "strngbad.h"
using std::cout;

//初始化static类成员;
int StringBad::num_strings = 0;

//类方法
StringBad::StringBad(const char* s)//构造函数
{
	len = std::strlen(s);//设置尺寸
	str = new char[len + 1];//分配存储空间
	std::strcpy(str, s);//初始化指针
	num_strings++;//设置对象数量
	cout << num_strings << ":\"" << str
		<< "\"对象创建\n";//提示信息
}

StringBad::StringBad()//默认构造函数
{
	len = 4;
	str = new char[4];
	std::strcpy(str, "C++");//默认字符串
	num_strings++;
	cout << num_strings << ":\"" << str
		<< "\" 默认对象创建\n";//提示信息
}

StringBad::~StringBad()//默认的析构函数
{
	cout << "\"" << str << "\"对象删除,";//提示信息
	--num_strings;
	cout << num_strings << " 左\n";
	delete[] str;
}

//友元函数
std::ostream& operator << (std::ostream& os, const StringBad& st)
{
	os << st.str;
	return os;
}

  不能在类中初始化静态成员变量,这是因为声明描述了如何分配内存,但不分配内存。可以用这种格式创建对象,从而分配和初始化内存。对于静态成员,可以在类声明之外使用单独的语句进行初始化,这是因为静态成员变量是单独存储的,不是对象的组成部分。

  初始化是在方法文件中,而不是在类声明文件中进行的,这是因为类声明位于头文件中,程序可能降头文件包括在其他几个文件中,如果在头文件中进行初始化,将出现多个初始化语句副本,从而引发错误。

  对于不能在类声明中初始化静态成员的一种例外情况是,静态成员为const整数或枚举型。

  字符串单独保存在堆内存中,对象仅保存了指出到哪里去查找字符串的信息。

str = s;

这只保存了地址,而没有创建字符串副本,不能这样做。

程序清单12.3vegnews.cpp

//2023年2月26日22:21:22
//vegnews.cpp -- 使用new和delete
#pragma warning(disable:4996)
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using std::cout;
#include "strngbad.h"

void callme1(StringBad&);//传递引用
void callme2(StringBad);//传递值

int main()
{
	using std::endl;
	{
		cout << "Starting an inner block.\n";
		StringBad headline1("Celery Stalks at Midnight");
		StringBad headline2("Lettuce Prey");
		StringBad sports("Spinach Leaves Bowl for Dollars");
		cout << "headline1: " << headline1 << endl;
		cout << "headline2: " << headline2 << endl;
		cout << "sports: " << sports << endl;
		callme1(headline1);
		cout << "headline1: " << headline1 << endl;
		callme2(headline2);
		cout << "headline2: " << 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 << "kont:" << knot << endl;
		cout << "Exiting the block.\n";
	}
	cout << "End of main()\n";

	system("pause");
	return EXIT_SUCCESS;
}

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";
}

标签:std,初始化,静态,StringBad,char,61,动态内存,strngbad
From: https://www.cnblogs.com/codemagiciant/p/17201804.html

相关文章

  • UVA11613 Acme Corporation
    UVA11613AcmeCorporation题意翻译已经很清楚了。思路看到这种求限制下的最值的问题,而且数据范围还比较小,我们不难想到费用流。但是这道题要求的是最大利润,那么我们可......
  • 动态内存申请
    malloc申请(堆区空间)头文件:#include<stdlib.h>void*malloc(size_tsize)size表示申请的空间字节数函数的返回值:成功:返回值为......
  • 力扣简617 合并二叉树
    一遍过欸但是没捋清楚所以写了好半天不过运行速度很差我发现我只会广度优先这题深度憨简单   classSolution{publicTreeNodemergeTrees(TreeNoder......
  • [Primer] 第 12 章 类和动态内存分配
    第12章类和动态内存分配12.1动态内存和类通常最好在程序运行时,而不是编译时决定内存的分配。不能在类声明中初始化静态变量,因为类声明仅仅提供了类的属性而没有分配......
  • 190615小记-生活从不容易
    2019-06-15生活从不容易,这句话虽然略显俗气。换了工作已经是一个半月了,心态好像好了一些。一直想写些东西总结一下,可是思维很混乱,网站也是很久没有更新。没什么重点,......
  • DELL R720/R720XD/R610
      DELLR720/R720XD/R610配置命令ipmitoolraw0x300x300x010x00#打开手动配置模式ipmitoolraw0x300x300x020xff0x05#低速5%ipmitoolraw0x300x300x0......
  • 为uniDBGrid设置文字操作栏(61)
    参考https://www.cnblogs.com/kinglandsoft/p/15117185.html为uniDBGrid设置文字操作栏,如下图的效果,用户点击审核,执行审核代码,点退回,执行退回代码: 对于Web应用界面,这是......
  • 新移科技4G全网通MTK6761安卓主板|安卓智能模块定制开发
    新移科技XY6761CA安卓核心板基于联发科MTK6761曦力A22平台,结合先进相机功能、丰富连接方式和轻量人工智能。是一款高性能低功耗的4G全网通安卓智能模块。   MTK6761......
  • HDOJ 2061-2070
    2061Treasurethenewstart,freshmen!ProblemDescriptionbackground:Anewsemestercomes,andtheHDUalsomeetsits50thbirthday.Nomatterwhat'syou......
  • hdu-2614
    取得第一个是第一个任务,时间0,接着进行下一个任务。#include<stdio.h>#include<iostream>#include<math.h>#include<stdlib.h>#include<ctype.h>#include<alg......