第12章类和动态内存分配
(1)  class  student
{char name[40];//并不是每一个字符串都是40//如果是一个对象数组,则浪费空间
};
12.1
(1)静态成员在类声明中声明,在包含类方法的文件中初始化。初始化时使作用域运算符来指出静态成员所属的类。但如果静态成员是整形或枚举型const,则可以在类声明中初始化
初始化 :   类型   类名::变量名 = 初始化的值
(2)析构函数在定义对象的代码块执行完毕时调用
12.1.2特殊成员函数
(1)c++自动提供成员函数:[1]默认构造函数,如果没有定义构造函数[2]默认析构函数,如果没有定义[3]复制构造函数,如果没有定义[4]赋值运算函数,如果没有定义[5]地址运算符,如果没有定义
(2)
#include<iostream>
#include<string.h>using namespace std;class CMyString
{public:static int m_nString;//创建对象的个数private:int len;char *m_nStr;public :CMyString(const char *str){m_nStr=new char [strlen(str)+1];strcpy(m_nStr,str);m_nString++;}CMyString (const CMyString &myStr){m_nString++;}~CMyString(){--m_nString;delete []m_nStr;}friend ostream & operator <<(ostream &os, CMyString &Str);
};
ostream & operator <<(ostream &os, CMyString &Str)
{os<<Str.m_nStr<<endl;return os;
}
int CMyString::m_nString=0;
int main()
{CMyString str("hello word");cout<<str;CMyString str1=str;cout<<CMyString::m_nString<<endl;return 0;
}
如果类中包含这样的静态数据成员,即其值将在新对象被创建时发生变化,则应该提供一个显示复制构造函数来处理计数问题
(3)浅拷贝:得到的是两个指向同一个字符串的指针
深度复制:应当将复制字符串并将副本的地址赋给str成员,
而不仅仅是复制字符串地址,这样每个对象都有自己的字符串,而不是引用另一个对象的字符串。调用析构函数时都将释放不同的字符串,而不会试图去释放已经被释放的字符串。
StringBad::String Bad(const StringBad &st)
{Num_strings++;len = st.len;str = new char =[len+1];std::strcpy(str,st.str);
}
(4)解决赋值的问题:
[1]由于目标对象可能引用了以前分配的数据,所以函数应使用delete[]
来释放这些数据
[2]函数应当避免将对象给自身;否则,给对象重新赋值前,释放内存操作可能删除对象的内容
[3]函数返回一个指向调用对象的引用
StringBad & StringBad::operator=(const StringBad &st)
{if(this==&st){return *this;}delete []str;len=str.len;str=new char[len+1];std::strcpy(str,st.str);return *this;
}
(5)
#include<iostream>
#include<string.h>
using namespace std;class CMyString
{private:char *m_pStr;int len;public:CMyString()/*C++11中空指针nullpstr*/{len = 0;m_pStr = new char [1];m_pStr[0] = '\0';}CMyString(const char *str){len=strlen(str);m_pStr = new char [len+1];strcpy(m_pStr,str);}const char & operator [](int index) const //对于const 对象只可以读{cout<<"Const"<<endl;return m_pStr[index];}char & operator [](int index)//读写常规的CMyString对象{cout<<"No Const"<<endl;return m_pStr[index];}friend ostream & operator<<(ostream &os,const CMyString &myString)  ;
};
ostream & operator <<(ostream &os, const CMyString &myString)
{os<<myString.m_pStr;return os;
}
int main()
{const CMyString str1("hello world");cout<<str1<<endl;char c=str1[7];cout<<c<<endl;cout<<str1[10]<<endl;CMyString str2 = "ni hao";cout<<str2[1]<<endl;//str2[1]='d';cout<<str2<<endl;return 0;
}
(6)
#include<iostream>
#include<string.h>using namespace std;
class String
{private:char *str;int len;static int num_strings;public:static const int CINLIM = 80;String (const char *s);//constructerString();String(const String &);~String();int length() const { return len; }public:String &operator = (const String &);String &operator = (const char *);char &operator [] (int i);const char & operator [](int i) const;public:friend bool operator<(const String &st,const String &st2);friend bool operator>(const String &st,const String &st2);friend bool operator==(const String &st,const String &st2);friend ostream & operator <<(ostream &os,const String &st);friend istream & operator >>(istream &is,const String &st);public :static int HowMany() { return num_strings;}
};int String::num_strings = 0;
String::String(const char *s)
{len=strlen(s);str = new char [len + 1];strcpy(str,s);num_strings++;
}
String::String()
{len = 4;str = new char [1];str[0] = '\0';num_strings++;
}
String::String(const String &st)
{len=st.len;str=new char[len+1];strcpy(str,st.str);num_strings++;
}
String::~String()
{--num_strings;delete []str;
}
String & String::operator=(const String &st)
{if(this==&st){return *this;}delete []str;len=st.len;str=new char [len+1];strcpy(str,st.str);return *this;
}
String & String::operator=(const char *s)
{delete []str;len=strlen(s);str = new char [len+1];strcpy(str,s);return *this;
}
char & String::operator[](int i)
{return str[i];
}
const char & String::operator [](int i)const
{return str[i];
}
bool operator<(const String &st1,const String &st2)
{return (strcmp(st1.str,st2.str)<0);
}
bool operator>(const String &st1,const String &st2)
{return st2<st1;
}
bool operator==(const String &st1,const String &st2)
{return (strcmp(st1.str,st2.str)==0);
}
ostream & operator <<(ostream &os,const String &st)
{os<< st.str;return os;
}
istream & operator >>(istream &is,String &st)
{char temp[String::CINLIM];is.get(temp,String::CINLIM);if(is){st=temp;while(is&&is.get()!='\n')continue;}return is;
}
int main()
{String str;cin>>str;cout<<str<<endl;cout<<str.length()<<endl;return 0;
}
12.4有关返回对象的说名
(1)如果方法或函数要返回局部对象,则应返回对象,而不是指向对象的引用。在这种情况下,将使用复制构造函数来生成返回的•对象。如果方法或函数要返回一个没有公有复制构造函数
的类(如ostream类)的对象,它必须返回一个指向这种对象的引用。
12.5.1
(1)析构函数的调用:[1]:如果对象是动态变量,则当执行完定义该对象的程序块时,将调用该对象的析构函数[2]静态变量(外部,静态,静态外部或来自命名空间),则在程序结束是将调用对象的析构函数[3]如果对象是用new创建的,则仅当使用delete删除对象是,其析构函数才会被调用
12.5.2
(1)析构函数可以自己调用
12.7
(1)成员初始化列表:[1]这种格式只能用于构造函数[2]必须使用这种格式来初始化非静态const数据成员[3]必须用这种格式初始化引用数据成员

第12章类和动态内存分配相关推荐

  1. C++ Primer plus 第12章类和动态内存分配复习题参考答案

    假设String类有如下私有成员 class String { private:char* str; //points to string allocated by newint len; //hol ...

  2. C++ Primer Plus(第六版)第12章 类和动态内存分配

    严重性代码说明项目文件行禁止显示状态 错误    C4996    'strcpy': This function or variable may be unsafe. Consider using ...

  3. 第十二章 类和动态内存分配

    静态成员变量 不能在类声明中初始化静态成员变量(声明描述了如何分配内存,但并不分配内存): 可以在类声明之外(在方法文件中)用单独的语句初始化静态成员变量: 初始化语句必须指出类型,并使用作用域解析运 ...

  4. 《C++ Primer Plus》读书笔记之十—类和动态内存分配

    第12章 类和动态内存分配 1.不能在类声明中初始化静态成员变量,这是因为声明描述了如何分配内存,但并不分配内存.可以在类声明之外使用单独的语句进行初始化,这是因为静态类成员是单独存储的,而不是对象的 ...

  5. C++ Primer Plus学习(十一)——类和动态内存分配

    类和动态内存分配 动态内存和类 静态类成员 特殊成员函数 string类的改进 构造函数中的new 返回对象 指向对象的指针 成员初始化列表(member initializer list) 动态内存 ...

  6. C++类与动态内存分配

    11.10 类与动态内存分配 通常,最好是在程序运行时(而不是编译时)确定诸如使用多少内存等问题.对于在对象中存储姓名来说,通常的C++方法是,在类构造函数中使用new运算符在程序运行时分配所需的内存 ...

  7. 第12章-cpp类和动态内存分配

    本章内容包括: • 对类成员使用动态内存分配. • 隐式和显式复制构造函数. • 隐式和显式重载赋值运算符. • 在构造函数中使用new所必须完成的工作. • 使用静态类成员. • 将定位new运算符 ...

  8. 读书笔记||类和动态内存分配

    一.动态内存和类 C++在分配内存的时候是让程序是在运行时决定内存分配,而不是在编译时再决定.C++使用new和delete运算符来动态控制内存.但是在类中使用这些运算符将导致许多新的编程问题,在这种 ...

  9. 类和动态内存分配——C++ Prime Plus CH12

    ①动态内存和类 1.复习示例和静态类成员 使用程序复习new和delete用法. // badstring.h文件 #include<iostream> #ifndef STRING_BA ...

最新文章

  1. Android开发实践:如何设置NDK的编译选项
  2. 工业互联网 — 5G TSN
  3. 对items函数的理解
  4. Vue 前端导出后端返回的excel文件
  5. mybatis和hibernate的区别---Mybatis的学习笔记(四)
  6. 简易的遍历文件加密解密
  7. Poj 3281 Regional Chengdu Food(Dicnic)
  8. php 修改input内容,JS简单获取并修改input文本框内容的方法示例
  9. python装饰器详解-如何理解Python装饰器?
  10. python和java的区别-python与java区别
  11. Docker 命令总结
  12. python 拆分字符串反斜杠_用反斜杠拆分字符串
  13. 输入框限制规则 只能输入数字 只能输入字母数字 等等
  14. 小白之WEB前端--第一篇
  15. 前言 金融大叔的梦想
  16. 小男孩学机器人编程好还是学钢琴好
  17. 机器学习入门1-译文-机器学习是什么以及它的重要性(machine learning--what it is and why it matters)
  18. 浅谈资金发展投资行业的发展路径
  19. 解释结构模型ISM-2-4
  20. 常用的服务器操作命令

热门文章

  1. Centos VMware 克隆后 网络配置
  2. 地理信息革命Geospatial Revolution
  3. 【转】关于微信开发者平台移动应用获取签名解决问题
  4. 在 Coding 上搭建 Hexo 个人博客!
  5. owa outlook使用中的一些问题-陆续添加
  6. win7下安装tomcat
  7. Linux下修改IP
  8. Linux 命令(36)—— awk 命令
  9. go 排序sort的使用
  10. 第四届蓝桥杯c/c++B组8