C++之封装

 

 

一、对象的生命历程与内存占用情况

 

二、类的对象的实例化

1、从栈实例化

 class TV 
{
//......
}; 

void main() 
{ 
TV tv; 
TV tv[20];
 }

 

 2、从堆实例化

 class TV 
{
//......
}; 

void main() 
{ 
TV *p=new TV(); 
TV *q=new TV[20];

//……

delete p;
p=NULL;
delete []q;
q=NULL:
 }

 

三、数据的封装

1.面向对象的基本思想:“谁来做什么”来表达程序的逻辑【以对象为中心】。体现在代码层面就是将所有的数据操作转化为成员函数的调用,即对象在程序中的所有行为都通过调用自己的函数来完成。

 

2.类内定义的成员函数,编译器将其优先编译为内联函数。

 

3.类外定义成员函数

<1>同文件类外定义:成员函数的定义与类的定义在同一个文件中(一个.cpp中)。

<2>分文件类外定义:在XXX.h(建议头文件文件名与类名一致)中声明类的所有数据成员和成员函数,在XXX.cpp中定义成员函数(注意将XXX.h包含进来)。

 

4.构造函数

<1>特点

 

<2>默认构造函数:在实例化对象时不需要传递参数的构造函数。

例:

class student
{
public:
student(){};
student (string name="Jim"){}
private:
string m_strName;
};

 

<3>拷贝构造函数

 

 

<4>构造函数初始化列表(建议使用)

 

 

 

 

补充说明:

1) const对象或引用只能初始化但是不能赋值。构造函数的函数体内只能做赋值而不是初始化,因此初始化const对象或引用的唯一机会是构造函数函数体之前的初始化列表中。

2)“初始式”可以调用类类型成员或基类构造函数。

3)  如果基类有默认构造函数(不需要传参数的构造函数),那么在实例化子类(包含对象成员的类)对象时可以不使用初始化列表;
如果基类构造函数要求必须有参数传入,则实例化子类对象时必须使用初始化列表的方式将相应的值传给基类成员(对象成员)。

 

<5>总结

 

 

<6>初始化对象成员问题:

class Coordinate
{
public:
Coordinate(int x,int y);
~Coordinate();
void setX(int x);
int getX();
void setY(int y);
int getY();

private:
int m_iX;
int m_iY;
};


class Line
{
public:
Line(int x1,int y1,int x2,int y2);
~Line();
void setA(int x,int y);
void setB(int x,int y);
void printInfo();

private:
Coordinate m_coorA;
Coordinate m_coorB;
};

 

Q:定义Line的构造函数时,为什么不可以写成如下形式却一定要用初始化列表呢?(编译error C2512: “Coordinate”: 没有合适的默认构造函数可用)

Line::Line(int x1,int y1,int x2,int y2)
{
m_coorA.setX(x1);
m_coorA.setY(y1);
m_coorB.setX(x2);
m_coorB.setY(y2);
cout<<"Line()"<<endl;
}

 

A:因为初始化列表会比构造函数先执行,再因为Coordinate是Line的对象成员,会优先于Line执行构造函数,
所以如果不把Coordinate的那两个对象放在初始化列表中进行初始化,将会导致Coordinnate的对象使用默认构造函数进行初始化,
然后你又没有写默认的构造函数,所以会报错,不过如果你写了默认构造函数,会导致多出来两个对象。因为实例化Line时,必须先实例化m_coorA和m_coorB,但这两个对象又无默认构造函数,所以要用初始化列表。

 

5.析构函数

 

四、类与对象总结

 

五、对象指针

this指针:指向对象自身数据的指针(this指针相当于它所在对象的地址)

this含义简单的来说,就是指向当前类的当前实例对象.。

对象1的this指针就是对象1的地址,对象2的this指针就是对象2的地址……【this指针指向的就是它所在对象本身的地址】

 

 

 六、常对象成员、常指针、常引用、常成员函数

 

1.常对象、常函数

<1>基本定义

常对象成员定义:const 类名 对象名 【类的数据成员前面加const】

常对象定义的语法:const 类名 对象名(参数列表)|| 类名 const 对象名(参数列表)//声明时必须初始化

 

常成员函数定义的语法:类型标识符 类名::函数名(参数列表) const 【常成员函数不能改变数据成员的值,注意const必须写在函数后面,与括号之间有空格】

常成员函数声明的语法:类型标识符 成员函数名(参数列表) const 【注意const必须写在函数声明的后面,分号之前】

 

 

举例说明:

 

互为重载说明常对象只能调用常成员函数.。


<2> 应用场合
常成员函数:如果一个成员函数对类中数据成员只作访问而不作直接或间接的修改,则最好将此函数设置为常成员函数,以明确表示它对数据成员的保护性。

常对象:必须进行初始化,常对象只能调用常成员函数。

 

<3> 为什么不能通过常指针去改变该指针指向的数据?

常指针的意思是指向常量的指针,数据本身就不能改变,但是指针指向的对象可以变。

 

<4>注意事项
1) 常对象只能调用常成员函数。

2) 普通对象可以调用全部成员函数。

3) 当对一个对象调用成员函数时,编译程序先将对象的地址赋给this指针,然后调用成员函数,每次成员函数存取数据成员时,由隐含使用this指针。

4) 当一个成员函数被调用时,自动向它传递一个隐含的参数,该参数是一个指向这个成员函数所在的对象的指针。

5) 在X类的const成员函数中,this指针的类型为:const X* const, 这说明this指针所指向的这种对象是不可修改的(即不能对这种对象的数据成员进行赋值操作);

 

 

 2.常指针、常引用

<1> 常指针和常引用都只能调用对象的常成员函数。

 

<2> const在前面,则是指向常变量的指针,const在后面,则是指向变量的常指针。

Coordinate * const p; // 指向常对象的指针

const Coordinate *p; // 指向对象的常指针


如果定义了一个指向常对象的指针变量,是不能通过它改变所指向的对象的值的,但是指针变量本身的值是可以改变的。

常指针一旦定义指向一个对象,那么它就不能再指向另一个对象了,但是能通过它改变所指向的对象的值.

 

 

 

posted @ 2018-09-18 22:22  eeeeeeee鹅  阅读(1043)  评论(0编辑  收藏  举报