天天看点

【一天一篇CPP】对象与指针与数组 对象和const和指针和引用

1.对象和数组:对于Student::Student( int a )而言Student stud[3] = {60,70,80};表示分别让60,70,80作为三个数组元素对象的构造函数的参数。//编译系统只为每个对象的构造函数传递一个参数,避免歧义

    易错例子: Student::Student(int = 1001, int = 18, int = 60),Student stud[3] = {100,200,300};//编译器让三个对象分别得到100,200,300,而不是一个对象得到全部

    错误例子:Student stud[3] = {100,200,300,400};//数组元素太多

2.对象数组的完整初始化

    Student stud[3] = {

    Student(100,18,87),

    Student(98,15,85),

    Student(105,16,85),

   };//这样就所有元素都能正确初始化。

3.对象和指针和数组

A指向对象的指针:略

B指向数据成员的指针 int *p1 = & t1.hour;

C指向函数成员的指针【与普通函数不同!!】

普通函数的指针:

void (*p)();
	p = &fun;
	(*p)();
           

成员函数的指针:

temp t;
	void (temp:: *p)();
	p = &temp::fun;
	(t.*p)();
           

需要先有一个对象【t】才能使用。【好像是这样,求指正】。

p = &temp::fun;
           

这句话中的&号在cpp中可以省略!

4.常对象【可以用来建立常量表】

Time const t1(12,34,46);

这样所有场合中,对象中所有数据成员都不能被修改【mutable类型也不能修改!】。凡是希望保证数据不被改变的对象,都可以声明为常对象。

形式:类名 const 对象名【也许跟着实参列表】; 或 const 类名 对象名【也许跟着实参列表】;

注意:一个对象被声明为常对象,就不能主动调用该对象的非const型成员函数。

例如:const Time t1(10,35,36); t1.getTime();//假如getTime是非const的,那么getTime被调用就会出错!假如为const类型则正确,所以记得将常对象的函数成员都定义为const成员函数

【编译器以文件为单位,不会知道另一个文件函数定义中是否修改了成员值,则编译器只敢调用const类型的函数【即常成员函数,这类型的函数编译器不让它修改成员值】,既然已经约定函数声明和定义都要加上const,那么这样调用const函数一定不能修改成员值,所以就算保险的!】

5.常成员函数:

写法:void Time::get_time() const;  const是函数的一部分,定义和声明都要有const 关键字。

特点:不能改变本类的成员数据值【除了mutable类型的】,不能调用非常的成员函数。

6.可变数据成员

将数据声明为mutable类型,如:mutable int count;

则count为可变数据成员,可用声明为const的常对象函数来修改它的值,也可以用其他函数修改,惟独常对象不能修改它。

7.常数据成员

如const int a;

则a只能被初始化显式改变,而不能去修改它。

8.常和对象的关系补充【省略可变数据成员情形】

如何灵活使用它们呢?

A.如果在一个类中,有些数据成员允许改变,另一些不变,则可将不变的声明为const类型的数据,非const成员函数可以修改一般成员的值,而不能修改const类型数据的值。

B如果所有数据成员都不用修改值,则可有二法:

一、数据全定义为const类型。

二、定义为常对象,只能使用其中的const成员函数对数据访问。

9.指向对象的常指针

Time t1,t2;

Time *const ptr = &t1; ptr1 = &t2;//常指针出错,不能改变指向【常用于函数的形参,不能修改指向】

10.指向常对象的指针变量

先复习常变量的指针变量

#include <iostream>

int main()
{
	const char c[] = "boy";
	const char *p1 = 0;
	p1 = c;		//可以改变指向
	//char *p2 = c;	//不合法,怕p2间接修改c数组的元素值

	//*p1 = 'a';	//不合法,不能修改值
	//c[0] = 'a';	//不合法,不能修改值


	char s[] = "abc";
	p1 = s;		//合法,虽然s不为const,但是
	s[0] = 'a';	//合法,别和1p搞懵
	*p1 = 'b';	//不合法,不能通过p1修改s的元素值
}
           

另外,如果函数形参是指向非const变量的指针,实参也只能是非const变量的指针。【还是编译器担心函数有可能修改const变量的值,所以函数形参也要匹配,和赋值的情况不同,非 常变量赋值给一个常变量的指针并没有错误】【另外这么做也能让调用者一清二楚,它的指向内容不会被改变】

以上这些对对象同样适用。

不沦是指向对象的常指针还是指向常对象的指针,大多都用于形参,对函数调用者提供一种保障。

如果希望某对象(变量)不变,则设为const,但是其指针类型也要相应变化。

11.对象的常引用

void fun( const Time &t)

对于引用,没有建立实参的拷贝,而是this的拷贝,不用大量申请内存的话,也不会进行复制构造函数的操作。