第一个c++程序

就到了毕业找工作的时候了,没有发现招C#的NB单位。C++ 、JAVA 不用说。考虑过后,还是C++ 吧,不久深入,但求应用。

不管怎么讲,C++ 的一个代码还是运行出来了,准确点是vc++ ,虽然我现在并不清楚他们的区别。还是把我的着第一个程序代码贴出来。亦为记。

#include <iostream.h>

struct Point

{

int x;

int y;

};

void main()

{

Point pt;

pt.x=5;

pt.y=5;

cout<<pt.x<<endl<<pt.y<<endl;

}

也可以修改为:

#include <iostream.h>

struct Point

{

int x;

int y;

void outPut()

{

cout<<x<<endl<<y<<endl;

}

};

void main()

{

Point pt;

pt.x=56;

pt.y=5;

pt.outPut();

//cout<<pt.x<<endl<<pt.y<<endl;

}

这里,函数被包含进了结构图当中,而在c语言中,结构体中是不能包含函数的。这样,我们就可以讲一些操作封装进结构图的内部,使用的时候只需要调用结构体内的方法就可以。

#include <iostream.h>

class Point

{

public:

int x;

int y;

void outPut()

{

cout<<x<<endl<<y<<endl;

}

};

void main()

{

Point pt;

pt.x=5;

pt.y=5;

pt.outPut();

//cout<<pt.x<<endl<<pt.y<<endl;

}

这里的改动很小,把关键词struct 改为了class,加上了class 标识符,这跟前面的运行结构都是一样的。在c++中,结构体和类可以通用,结构体也是一种特殊的类,这里的struct和类还是有一定的区别,他们的区别主要在访问控制方面,比如,在上面的程序中,将public 注释,编译,报错“不能访问类中的私有成员”,在结构体中,所有的成员缺省情况都是public ,也就是在外部都是可以直接访问的。而对于一个类来讲,所有的函数和成员在默认的情况下都是私有的,不能够被外部访问。

数据成员和成员函数,

类的一个实例就是一个对象

把所有的方法放在类上,替代使用参数,方法的方式,使得方法由实例或者是方法来提供

下面假设我们忘记给x和y赋值,来检查运行的结果

#include <iostream.h>

class Point

{

public:

int x;

int y;

void outPut()

{ cout<<x<<endl<<y<<endl;

}

};

void main()

{

Point pt;

//pt.x=5;

//pt.y=5;

pt.outPut();

//cout<<pt.x<<endl<<pt.y<<endl;

}

运行结果:

-858993460

-858993460

可以看到,这是两个很大的负数,这是因为在没有赋值的情况下,系统随机给x、y赋予了这些值,(我觉得好像也不是任意随机的拉)

针对这样的情况,我们可以采用如下的方法,直接在类中加上初始化的函数,然后实例化类后再调用这个初始的函数就可以了。如下:

Code

#include <iostream.h>

class Point

{

public:

int x;

int y;

void init()

{

x=0;

y=0;

}

void outPut()

{

cout<<x<<endl<<y<<endl;

}

};

void main()

{

Point pt;

pt.init();

//pt.x=5;

//pt.y=5;

pt.outPut();

//cout<<pt.x<<endl<<pt.y<<endl;

}

运行结果如下:

0

0

然而有的时候呢,我们会忘记去调用这个初始化的函数,而实际上呢,c++已经帮我们想好了,好,现在该构造函数出场了。

#include <iostream.h>

class Point

{

public:

int x;

int y;

/* void init()

{

x=0;

y=0;

}

*/

Point()

{

x=0;

y=0;

}

void outPut()

{

cout<<x<<endl<<y<<endl;

}

};

void main()

{

Point pt;

// pt.init();

//pt.x=5;

//pt.y=5;

pt.outPut();

//cout<<pt.x<<endl<<pt.y<<endl;

}

上面程序中,pt.init();已经被注释了,在类中,我加上了这么一个特殊的函数,函数的名字就是类的名字,大小写要一致,并且这个函数没有返回值。

上面的函数的运行结果呢,也是

0

0

虽然我们没有去调用这个构造函数,但是x,y 是已经被初始化的了。关于函数执行顺序,可以通过设置断点,F5 或者是F10(单步执行step over)进行查看。

构造函数作用

1.初始化内部的数据成员,更重要的作用是创建对象本身

2.C++规定,每个类必须有一个构造函数,没有构造函数,就不能创建任何对象。

3.C++规定,如果一个类没有提供任何的构造函数,C++会提供一个默认的构造函数(由编译器提供),这个默认的构造函数是一个不带任何参数的构造函数,它只负责创建对象,而不做任何的初始化工作。(这就是在我们前面程序中,没有使用任何构造函数,但也创建了实例的原因)

4.只要一个类定义了一个构造函数,不管是否是带参数的构造函数,C++ 就不再提供默认的构造函数。也就是说,如果为一个类定义了一个带参数的构造函数,还想要无参的构造函数,则必须自己定义。

既然创建了一个对象,就会在计算机中占据一定的内存,而内存的分配,就是由构造函数来完成。

好,上面在对象的生成的时候,为对象分配了一定内存空间,同样,在对象使用结束的时候,c++ 也提供了对象的销毁函数,这样呢,在程序完成后(生命周期结束),会调用析构函数,释放内存。

例子如下:

#include <iostream.h>

class Point

{

public:

int x;

int y;

/* void init()

{

x=0;

y=0;

}

*/

Point()

{

x=0;

y=0;

}

~Point()

{

}

void outPut()

{

cout<<x<<endl<<y<<endl;

}

};

void main()

{

Point pt;

// pt.init();

//pt.x=5;

//pt.y=5;

pt.outPut();

//cout<<pt.x<<endl<<pt.y<<endl;

}

构造函数和析构函数都是系统自动完成的。

析构函数特性:

1.当一个对象的生命周期结束时,其所占用的内存空间就要被回收,这个工作由析构函数完成。

2.析构函数是反向的构造函数,析构函数不允许有返回值,更重要的是析构函数不能带任何参数,并且一个类中只能有一个析构函数。

3.析构函数的作用和构造函数作用相反,对象超出其作用范围,对应的内存空间被系统回收或者程序用delete删除时,析构函数会被调用。

4.根据析构函数的这种特点,我们可以在构造函数中初始化对象的某些成员变量,给其分配内存空间(堆内存),在析构函数中释放对象在运行期间申请的资源空间。

现在我们看看什么有参的构造函数

#include <iostream.h>

class Point

{

public:

int x;

int y;

/* void init()

{

x=0;

y=0;

}

*/

Point()

{

x=0;

y=0;

}

Point(int a,int b)

{

x=a;

y=b;

}

~Point()

{

}

void outPut()

{

cout<<x<<endl<<y<<endl;

}

};

void main()

{

Point pt(3,3);

// pt.init();

//pt.x=5;

//pt.y=5;

pt.outPut();

//cout<<pt.x<<endl<<pt.y<<endl;

}

有参的构造函数和无参的构造函数的名称是一样的,曰:函数的重载。

函数重载构成的条件:函数的参数类型,参数的个数不同,才能构成函数的重载。

Viod outPut() 和int outPut() 是不能构成重载函数的。//只有返回值不同的函数不能构成重载

Void output(int a, int b=5) 和void output(int a )也是不能构成函数重载的,第一个是函数的第二个参数是个缺省值,实际上,这个参数的调用只要一个参数即可。

#include <iostream.h>

class Point

{

public:

int x;

int y;

/* void init()

{

x=0;

y=0;

}

*/

Point()

{

x=0;

y=0;

}

Point(int a,int b)

{

x=a;

y=b;

}

~Point()

{

}

void outPut()

{

cout<<x<<endl<<y<<endl;

}

void outPut(int x,int y)

{

x=x;

y=y;

}

};

void main()

{

Point pt(3,3);

pt.outPut(5,5);

// pt.init();

//pt.x=5;

//pt.y=5;

pt.outPut();

//cout<<pt.x<<endl<<pt.y<<endl;

}

上面并没有完成我们想要的功能,这实际上是变量的一个可见性的问题,

void outPut(int x,int y)

{

x=x;

y=y;

}

结果:

3

3

我们所有的操作,实际上都是对形参进行的操作,而整个个外面的x.,y 成员变量是没有受到任何的影响。

我们也可以将output(int x, int y)换为a,b,这样是可以的。

#include <iostream.h>

class Point

{

public:

int x;

int y;

/* void init()

{

x=0;

y=0;

}

*/

Point()

{

x=0;

y=0;

}

Point(int a,int b)

{

x=a;

y=b;

}

~Point()

{

}

void outPut()

{

cout<<x<<endl<<y<<endl;

}

void outPut(int a,int b)

{

x=a;

y=b;

}

};

void main()

{

Point pt(3,3);

pt.outPut(5,5);

// pt.init();

//pt.x=5;

//pt.y=5;

pt.outPut();

//cout<<pt.x<<endl<<pt.y<<endl;

}

结果

5

5

假设我们还是想用x,y 来表示形参,可以改为下面的形式

void outPut(int x,int y)

{

this->x=x;

this->y=y;

}

这样,运行结果

5

5

其中的 this 指的是对象本身。

关于this指针

1.this指针是一个隐含指针,它指向对象(而不是类)的本身,代表了对象的地址。

2.一个类所有的对象调用的成员函数都是同一代码段。

在对象调用pt.outPut(10,10)时候,成员函数除了接收两个实参之外,还接收了一个对象的地址 ,这个地址被一个隐含的形参指针this所获取,等同于执行 this=&pt。所有对数据成员的访问都被隐含加上了前缀this->.如x=0,等价与this->x=0.

贴出来回看了一下,咋个是这么的不友好,以后再接再厉。