简析类与对象,组合类,派生类的初始化过程

1,  类和对象如何区分??异同点呢??

2,  什么是组合类,它的初始化过程呢??

3,  私有成员变量可以被对象访问吗??

4,  派生类呢??它的初始化过程呢??加入基类中带有构造函数呢??



关于类和对象,我们先来说一说:

类:简单的来讲就是有自己的属性和操作方法(行为),是一个抽象的概念,不存在于现实的时间和空间里,只是为所有的对象定义了抽象的属性与行为,如同:动物anmial是一个类,可以包含很多的个体,但就是不存在于这个世界,这是一个静态的概念,本身不携带任何数据


对象:是一个具体的,实实在在的东西,是一个动态的概念,是占用存储空间的,是一个事物,比如动物anmial类中的狗就是一个对象

异同:类是对象的抽象,对象是类的具体实例,类是抽象的,不占存储空间,对象是具体的,占用内存空间

           类:动物                   对象:狗


对于C++:
1.    C++中的结构不仅可以包含不同类型的数据,而且还可以包含函数。

2.    结构中的数据和函数都是结构的成员,分别称为数据成员和函数成员(C++中,也称函数为成员函数,称变量为  成员变量)

3.    C++类的成员函数描述了对类对象内部数据的操作方法,或者说,描述了对象的行为,因此,又将成员函数称为方法(method)或者服务(service)

4.    定义一个类的多个对象时,每一个对象拥有自己的数据成员,称为实例变量,它们各自占据不同的内存空间,但他们共用一份成员函数,这是因为同一个类的成员函数的代码是相同的,共用一份成员函数可以节省内存空间。在内存中对象的实例变量和成员函数是分开存放的,我们的成员函数通过隐藏的this指针(C++编译器自己加的)指向不同的对象来决定使用哪一个对象的数据成员

5.    类的成员变量和成员函数构成了类的接口,成员函数的定义部分称为类的实现(个人理解)



对于私有成员变量:

这意味着这些变量只能被当前类中的其他成员函数访问,外界不能访问(即为封装),不能被对象直接访问,不然可能会产生非法访问,但是如果我们把变量用public声明,那么成员函数和对象都是可以访问的,

C++规定,默认的情况下,类中的成员(数据成员,函数成员)是私有的



类的声明和定义

准确的说法是:

                         类的声明:一旦给出了类头,就声明了一个类,可以声明一个类但是不定义它,如:class  Date;

                         类的定义:包含类头和类体,一旦看到类的结尾,即结束右边的花括号,这时就定义完毕

一个类仅仅被声明,那么就不能定义这种类类型的对象,因为不能确定这种类类型的大小,编译器就不知道应该分配给多少这样的存储空间,但是我们可以声明这种类类型对象的指针,因为他们与对象所占的存储空间大小无关



如果两个对象属于同一种类型,也就是说:两个对象是由同一个类声明的,那么我们可以将其中的一个对象的值(属性值)赋给另一个对象,其中数据是按位复制到第二个对象中的。但是,对象的赋值仅仅是说明两个对象的值是相等的,而这两个对象仍然是相互独立的,也就是说,修改一个对象中的值不会影响另一个对象


1,关于组合类,对象成员

      下面我们来看这个程序:

class  Date                                                         class Student 

{                                                                          {

          int  day;                                                          private:            

          int  month;                                                           int      number;

          int  year;                                                              char   name[15];

          public:                                                                 Date  birthday;

                   Date(int dd, int mm, int yy);                        float   score;

                   void print();                                                 public:

}                                                                                            ..........;

                                                                            }

一个类的成员是另一个类的对象,可以看出Student类有一个成员是类Date的对象(birthday),

我们称birthday为Student类的对象成员,而将Student类称为组合类


一般我们都知道:有构造函数的话,在创建对象的话,会默认的调用构造函数对其进行初始化,但是如果碰见上面这种情况,该如何处理呢??



#include                                                                                                                              
#include 
using namespace std;

class Date
{
        private:
                int day, month, year;   
        public:
                Date(int dd, int mm, int yy);
                void print()
                {       cout<

运行结果:

有一个警告:(warning: deprecated conversion from string constant to ‘char*’)

但是我们的程序是可以正常运行的,正常的对这个组合类进行初始化的

所以说:当我们对其初始化的时候应该这样做:

Student::Student(int number1, char *name1, float score1, int d1, int m1, int y1):birthday(d1, m1, y1)
{
        number = number1;
        strcpy(name, name1);
        score = score1; 
}

大家注意这个构造函数后面的东西,这应该就是间接的调用了对象成员的构造函数

所以当我们进行创建类的对象时,是默认的调用了自己的构造函数,但是当成员是对象的时候,也就间接的调用了对象成员的构造函数,值得注意的是:定义组合类的构造函数时,必须将对象成员的构造函数写在后面!!!

对于类体内定义的成员函数,编译时,是按内联函数处理的,例如上面程序中类里面的print函数就是的,还有就是用inline进行声明的,编译时直接对调用处进行替换的过程,类似与c中的宏,本质就是牺牲空间换取时间

对于类体外定义的成员函数,我们必须加上类名和作用域解析运算符(“::”)

其中作用域解析运算符用来连接类名和成员名,告知编译器这个成员属于那个类



派生类的构造函数:

#include 
#include 
using namespace std;

class stud
{
        public :
                int num;
                char name[10];
                char sex;
        public:
                stud(int n, char na[], char s)
                {                                                                                                                               
                        n = num;
                        strcpy(name, na);
                        sex = s;        
                }       
                ~stud()   {}
};

class student:public stud
{
        private:
                int age;
                char addr[30];
        public :
                student(int n, char na[], char s, int a, char ad[]):stud(n, na, s)
                {
                        age = a;
                        strcpy(addr, ad);       
                }       

                void show()
                {
                        cout<<"num:"<

当基类中含有带参数的构造函数时, 派生类的构造函数必须说明基类所需要的所有参数,其构造函数一般格式如下:

派生类构造函数名(参数表):基类构造函数名(参数表)

 student(int n, char na[], char s, int a, char ad[]):stud(n, na, s)

其实,我们可以看出,派生类的构造函数是五个参数,而基类是三个参数,所以,派生类构造函数的前三个参数传递给了基类,值得注意的是,这三个参数应该在前面,不能放在后面,因为基类必须先初始化



内联函数:

首先来看函数调用的实质:其实是将程序执行转移到被调用函数所存放的内存地址,将函数执行完后,在返回到执行此函数的地方,这种转移操作需要保护现场(包括各种函数的参数的进栈操作),在被调用函数代码执行完后在恢复现场。但就是恢复现场和保护现场需要很大的资源开销。

对于一些较小的函数而言,若是调用频繁,函数的调用过程可能会比函数执行需要的系统资源更多,会更加得不偿失,所以引入了内联函数

是由编译器来将程序中出现的内联函数进行替换的过程


static:(在C++中,通过在类的成员前面加static关键字将其成员声明为静态成员,(可为:静态数据成员,静态函数成员))

静态成员变量一定应该在创建类的对象前进行定义并初始化

(int  student::count = 0)其中student为类名,count为静态成员变量

一个类的静态数据成员为该类所有对象共用,不管我们创建了这个类的多少个对象,其静态数据成员在内存中只有一份拷贝,因为只有一份拷贝,所以我们经常使用(类名::)来访问静态数据成员.

当然,全局变量也可以实现数据的共享,当相对而言,封装性就不是很好了


一般来说:类的静态成员函数(加上关键字static,不能声明为const)是用来访问静态数据成员,当然也可以访问全局变量,静态成员函数不具有this指针,也就是说,静态成员函数不与某个具体的对象相联系,它只是属于该类。

调用该方法时:不会将对象的引用传递给他,所以在static方法中不可访问非static成员


友元函数:

一个类的友元函数是在该类中说明的一个非成员函数,但允许访问该类对象的所有成员,通常我们将友元函数的原型放在类的声明的public部分,并在函数声明的前面加上一个friend关键字。

如:

friend double Distance(Point &a, Point &b);在类中


定义的时候是不需要类名的。

double Distance(Point &a, Point &b)

{


}

友元函数可以直接访问对象的私有成员,节省了调用成员函数的开销,从而提高了程序的运行效率,所以引入了友元函数,当然,使用友元也就破坏了封装,降低了可维护性,因为友元函数并不是类的成员,所以在友元函数中没有this指针,因此必须通过参数来传递对象

你可能感兴趣的:(c++/c)