c++第十一天类和动态内存分配

特殊成员函数

  • 默认构造函数,如果没有定义构造 函数;
  • 默认析构函数, 如果没有定义;
  • 复制构造函数, 如果没有定义;
  • 赋值运算符, 如果没有定义;
  • 地址运算符, 如果没有定义。
默认构造函数

如果没有提供任何构造函数,编译器将提供一个没有任何参数,不执行任何操作的默认构造函数.
只能有一个默认构造函数.
带参数的构造函数也可以是默认构造函数,只要所有参数都有默认值

复制构造函数

用于将一个对象复制到新创建的对象中,它用于初始化过程而不是常规的赋值过程.类似构造如下:

Class_name (const Class_name &);

她接受一个指向类对象的常量引用作为参数.

调用时机 : 新建一个对象并将其初始化为同类的现有的对象的时候,复制构造函数将被调用.

Class StaingBad;
StringBad ditto(motto);
StringBad metto = motto;
StringBad also = StringBad(motto);
StringBad *string = new StringBad(motto);

每当程序生成对象副本时都将使用复制构造函数,具体的说: 当函数按值传递时或函数返回对象时都将使用复制构造函数.
默认复制构造函数逐个复制非静态成员(静态成员不需要,静态成员属于整个类而不是对象),称为成员复制或者浅复制

StringBad sailor = motto;
//等价于
StringBad sailor;
sailor.str = motto.str;
sailor.len= motto.len;

深度复制和浅复制
深度复制: 如 果类中包含了使用new初始化的指针成员, 应当定义一个复制构造函数,以 复制指向的数据,
浅复制: 浅 复制仅浅浅地复制指针信息, 而不会深入“ 挖掘” 以复制指针引用的结构。

赋值运算符

c++允许类对象赋值,通过重载 ’ = ’ 运算符实现 . 将已有的对象赋给另一个对象时将使用重载的赋值运算符.
赋值运算符的隐式实现也对成员进行逐个复制。 如果成员本身就是类对象, 则程序将使用为这个类定义的赋值运算符来复制 该成员.
赋值 操作并不创建新的对象.在赋值时需要注意:

  • 由于目标对象可能引用了以前分配的数据, 所以函数应使用delete[ ]来释放这些数据。
  • 函数应当避免将 对象赋给自身; 否则, 给对象重新赋值 前, 释放内存操作可能删除对象的内容。
  • 函数返回一个指向调用对象的引用.
StringBad &StringBad ::operator =(const StringBad &st){
	if(this == st)
		return *this;
	delete []str;
	len = st.len;
	str = new char [len+1];
	std::strcpy(str,st.str);
	retrurn *this.

}
比较函数
使用中括号表示法访问字符.重载’[ ]’

在重载 时, C++ 将 区分常量 和非常量函数 的特征标, 因此可以提供一个仅供 const String对象使用的operator 版本:
.

char & String::operator[](int i){
 	return str[i];
}

const char & String::operator[](int i)const
{
	return str[i];
}
静态类成员函数

可以 将成员函数 声明为静态的( 函数声明必须包含关键字 static, 但如 果函数定义是独立 的, 则其中不能包含关键字 static),

不能 通过对象调用静态成员 函数; 静态成员函数不能 使用 this 指针。 如果 静态成员函数是在公有部分声明 的, 则可以 使用 类名和作用域解析运算符来调用它。

在构造函数中使用new 的注意事项

  • 如果在构造函数中使用 new 来 初始化 指针 成员, 则应在析构函数中使用delete。
  • new 和 delete 必须相互兼容。 new对应于delete, new[ ]对应于delete[ ]。
  • 如果有多个构造函数, 必须以相同的方式使用 new, 要么都带中 括号, 要么都不带。 因为只有 一个 析 构 函数,所有的 构造函数 都必须与它兼容。 然而, 可以在 一个构造函数中使用new 初始化指针, 而在另一个 构造函数中将指针初始化为 空 0 或 C++ 11 中的 nullptr),这是因为delete(无论是 带 中 括号 还是 不带 中 括号可以用于空 指针。

NULL、 0 还是nullptr: 以前,空指针可以用 0 或 NULL( 在很多头文件中, NULL 是 一个 被定义 为 0 的符号常量) 来表示。 C 程序员通常使用NULL 而不是 0, 以指出这是一个指针, 就像使用‘\ 0’ 而 不是 0 来表示空字符, 以指 出这是一个字符 一样。C++ 传统上 喜欢用简单的0 , 而不是等价 的 NULL。 但正如前面 指出 的, C++ 11 提供了关键字nullptr,这是 一种更好的选择。

函数返回一个对象

返回指向const 对象的引用

可以提高效率. 如果函数返回(通过调用对象的方法或将对象作为参数) 传递给它的对象,可以通过返回引用来提高其效率。

返回 指向 非 const 对象 的 引用.

两种常见的 返回 非 const 对象情形是, 重载赋值运算符以及重载与cout 一起使用 的<< 运算符。 前者这样做旨在提高效率, 而后者必须这样做。

返回对象

如果被返回的对象是被调用函数中的局部变量, 则不应按引用方式返回 它, 因为在被调用 函数 执行 完毕 时, 局部对象将 调用其析构 函数。 因此, 当控制权回到调用函数时, 引用 指向的对象 将不再存在。 在这种情况下,应返回对象而不是引用。

返回const 对象

在设计类时可以看看原书第12章最后的几个案例.

你可能感兴趣的:(c++primer学习记录,c++)