个人觉得学习编程最有效的方法是阅读专业的书籍,通过阅读专业书籍可以构建更加系统化的知识体系 一直以来都很想深入学习一下C ,将其作为自己的主力开发语言现在为了完成自己这一直以来的心愿,准备认真学习《C Primer Plus》 为了提高学习效率,在学习的过程中将通过发布学习笔记的方式,持续记录自己学习C 的过程,今天小编就来说说关于cprimerplus讲没讲排序算法:CPrimerPlus学习笔记之类和动态内存分配?下面更多详细答案一起来看看吧!

cprimerplus讲没讲排序算法:CPrimerPlus学习笔记之类和动态内存分配

cprimerplus讲没讲排序算法:CPrimerPlus学习笔记之类和动态内存分配

前言

个人觉得学习编程最有效的方法是阅读专业的书籍,通过阅读专业书籍可以构建更加系统化的知识体系。 一直以来都很想深入学习一下C ,将其作为自己的主力开发语言。现在为了完成自己这一直以来的心愿,准备认真学习《C Primer Plus》。 为了提高学习效率,在学习的过程中将通过发布学习笔记的方式,持续记录自己学习C 的过程。

一、动态内存和类

不能在类声明中初始化静态成员变量,因为声明描述了如何分配内存,但并不分配内存。对于静态类成员,可以在类声明之外使用单独的语句来初始化,因为静态类成员是单独存储的,而不是对象的组成部分。初始化语句指出了类型,并使用了作用域运算符,但没有使用关键字static。

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

删除对象可以释放对象本身占用的内存,但并不能自动释放属于对象成员的指针指向的内存。因此,必须使用析构函数。

将一个对象赋值给另一个对象,代码如下:

StringBad sailor = sports;

以上代码等效于下面的代码:

StringBad sailor = StringBad(sports);

对应的原型如下:

StringBad(const StringBad &);

C 自动提供了下面这些成员函数:

在新建一个对象并将其初始化为同类现有对象时,复制构造函数都将被调用。按值传递意味着创建原始变量的一个副本。 默认的复制构造函数逐个复制非静态成员(成员复制也称为浅复制),复制的是成员的值。

将已有的对象赋给另一个对象时,将使用重载的复制运算符。

二、改进后的新String类

语句str = new char[1];与str = new char;两种方式分配的内存量相同,区别在与前者与类析构函数兼容,而后者不兼容。

C 提供一个新的关键字nullptr,用于表示空指针。

在C 中,两个中括号组成一个运算符——中括号运算符,可以使用方法operator[]()来重载该运算符。

可以将成员函数声明为静态的(函数声明必须包含关键字static,但如果函数定义是独立的,则其中不能包含关键字static),这样做有两个重要的后果:

  1. 不能通过对象调用静态成员函数;实际上,静态成员函数甚至不能使用this指针。如果静态成员函数是在公有部分声明的,可以使用类名和作用域解析运算符来调用它。
  2. 由于静态函数不与特定的对象相关联,因此只能使用静态数据成员。
三、在构造函数中使用new时应注意的事项

至此,您知道使用new初始化对象的指针成员时必须特别小心。具体地说,应当这样做:

四、有关返回对象的说明

当成员函数或独立的函数返回对象时,有几种返回方式可供选择。可以返回指向对象的引用、指向对象的const引用或const对象。 使用const引用的常见原因是旨在提高效率,如果函数返回(通过调用对象的方法或将对象作为参数)传递给它的对象,可以通过返回引用来提高效率。 两种常见的返回非const对象情形是,重载赋值运算符以及重载与cout一起使用的运算符。前者这样做旨在提高效率,而后者必须这样做。 如果被返回的对象是被调用函数中的局部变量,则不应按引用方式返回它,因为在被调用函数执行完毕时,局部对象将调用其析构函数。因此,当控制权回到调用函数时,引用指向的对象将不再存在。在这种情况下,应返回对象而不是引用。通常,被重载的算术运算符属于这一类。

五、使用指向对象的指针

在下属情况下析构函数将被调用:

使用对象指针时,需要注意几点:

String * glamour;

String * first = &sayings[0];

String * favorite = new String(sayings[choice]);

//调用默认构造函数 String * gleep = new String; //调用String(const char *)构造函数 String * glop = new String("mymy"); //调用String(const String &)构造函数 String * favorite = new String(sayings[choice]);

if(sayings[i].length() < shortest -> length())

if(sayings[i] < *first) first = &sayings[i];

六、复习各种技术1、重载<<运算符

要重新定义<<运算符,以便将它和cout一起用来显示对象的内容,请定义下面的友元运算符函数:

ostream & operator<<(ostream & os, const c_name & obj) { os << ...; return os; }

其中c_name是类名。

2、转换函数

要将单个值转换为类类型,需要创建原型如下所示的类构造函数:

c_name(type_name value);

其中c_name为类名,type_name是要转换的类型的名称。 要将类转换为其他类型,需要创建原型如下所示的类成员函数:

operator type_name();

虽然该函数没有声明返回类型,但应返回所需类型的值。 可以在声明构造函数时使用关键字explicit,以防止它被用于隐式转换。

3、其构造函数使用new的类

注意以下几点:

className(const className &)

c_name & c_name::operator=(const c_name & cn) { if(this == & cn) return *this; delete [] c_pointer; c_pointer = new type_name[size]; ... return *this; }

七、队列模拟

在类声明中声明的结构、类和枚举被称为是嵌套在类中,其作用域为整个类。

对于const数据成员,必须在执行到构造函数体之前,即创建对象时进行初始化。C 提供了一种特殊的语法来完成这种工作,它叫做成员初始化列表(member initializer list)。成员初始化列表由逗号分隔的初始化列表组成(前面带冒号)它位于参数列表的有括号之后、函数体左括号之前。例如:

Queue:Queue(int qs) : qsize(qs)//初始化qsize值为qs { front = rear = NULL; items = 0; }

只有构造函数可以使用这种初始化列表语法。对于const类成员和被声明为引用的类成员,必须使用这种语法。 数据成员被初始化的顺序与它们出现在类声明中的顺序相同,与初始化器中的排列顺序无关。

定义伪私有方法,可以避免本来将自动生成的默认方法定义,和这些方法是私有的不能广泛使用。

,