vs2015&C++学习笔记2

1、举例:foo(string s, int i):name(s), id(i){} ; // 初始化列表
  即将字符串s的值赋给name。
2、默认构造函数:没有参数或参数有默认值的构造函数
  class();或class(int age=12,name="xiao ming");
  

二、必须使用参数初始化列表的情况
  1、初始化引用成员
  2、初始化const变量
  3、初始化没有默认构造函数的类成员,包括基类没有默认构造函数

C++标准规定:delete空指针是合法的,没有副作用。所以我们一般在delete后就以为万事大吉了,其实这是不安全的。

  我们在Delete指针后赋值为NULL或0是个好习惯。对一个非空指针delete后,若没有赋NULL,若再次delete的话

有可能出现问题。如下代码:

可以看出delete是释放指针指向的内存,并不是指针本身所占有的内存。所以delete后,指针的还是指向那块区域,并

未清0,所以如果下次用到,就会发生xxx空间不能访问的异常。

所以以后delete后要赋值为空,这样就不会产生一些不可预知的内存错误。

空指针是一个特殊的指针值。

空指针是指可以确保没有指向任何一个对象的指针。通常使用宏定义NULL来表示空指针常量值。NULL就代表系统的0地址单元

空指针确保它和任何非空指针进行比较都不会相等,因此经常作为函数发生异常时的返回值使用。

new和delete

  • 使用new创建对象,delete销毁对象
    使用new创建一个动态类对象时,要执行三个步骤:
    a)调用名为operator new的标准库函数,分配足够大的内存。
    b)调用该类的一个构造函数,创建对象
    c)返回执向该对象的指针
    使用delete删除时,要执行两个步骤:
    a)如果类对象有析构函数则调用析构
    b)释放类对象所占堆空间

引用是一个变量,它引用其他变量的内存位置。例如,来看以下代码:

int x = 34;
int &lRef = x;

在该代码中,标识符 IRef 就是一个引用。在声明中,引用是通过 & 符号来指示的,它出现在类型与变量的标识符之间,这种类型的引用称为左值引用。

可以将左值看作是一个关联了名称的内存位置,允许程序的其他部分来访问它。在这里,我们将 "名称" 解释为任何可用于访问内存位置的表达式。所以,如果 arr 是一个数组,那么 arr[1] 和 *(arr+1) 都将被视为相同内存位置的“名称”。

相对而言,右值则是一个临时值,它不能被程序的其他部分访问。为了说明这些概念,请看以下程序段:

 
  1. int square(int a)
  2. {
  3. return a * a;
  4. }
  5. int main()
  6. {
  7. int x = 0; // 1
  8. x = 12; // 2
  9. cout << x << endl; // 3
  10. x = square(5); // 4
  11. cout << x << endl; // 5
  12. return 0;
  13. }

在该程序中,x 是一个左值,这是因为 x 代表一个内存位置,它可以被程序的其他部分访问,例如上面注释的第 2、3、4 和 5 行。

而表达式 square(5) 却是一个右值,因为它代表了一个由编译器创建的临时内存位置,以保存由函数返回的值。该内存位置仅被访问一次,也就是在第 4 行赋值语句的右侧。在此之后,它就会立即被删除,再也不能被访问了。

对于包含右值的内存位置来说,其本质就是:它虽然没有名称,但是可以从程序的其他部分访问到它。

C++11 引入了右值引用的概念,以表示一个本应没有名称的临时对象。右值引用的声明与左值引用类似,但是它使用的是 2 个 & 符号(&&),以下代码使用了右值引用打印了两次 5 的平方:

 
  1. int && rRef = square(5);
  2. cout << rRef << endl;
  3. cout << rRef << endl;

有意思的是,声明一个右值引用,给一个临时内存位置分配一个名称,这使得程序的其他部分访问该内存位置成为了可能,并且可以将这个临时位置变成一个左值。

右值引用不能约束到左值上,所以,以下代码将无法编译:

int x = 0;
int && rRefX = x;

再来看以下初始化语句:

int && rRef1 = square(5);

在初始化完成之后,这个包含值 square(5) 的内存位置有了一个名称,即 rRef1,所以 rRef1 本身变成了一个左值。这意味着后面的这个初始化语句将不会编译:

int && rRef2 = rRef1;

究其原因,就是右侧的 rRef1 不再是一个右值。综上所述,临时对象最多可以有一个左值引用指向它。如果函数有一个临时对象的左值引用,则可以确认,程序的其他部分都不能访问相同的对象。

发布了25 篇原创文章 · 获赞 139 · 访问量 116万+

猜你喜欢

转载自blog.csdn.net/shenwansan_gz/article/details/105008666