您的位置:首页 > 编程语言 > C语言/C++

c++之基于对象程序设计

2011-09-15 13:25 246 查看
一、概括:

1.1、解决复杂问题的途径无非就是把问题分割成简单的问题。

1.2、在面向过程的编程语言中(例如c语言),我们考虑问题的核心是过程、是算法、是解决问题的步骤,其次才是算法过程中需要的数据。所以对于c语言来说,分割复杂问题理所当然就是对过程的分割,我们把整个程序过程分割成函数,然后可以把函数按照功能或者其他规则分别存储在多个源文件中。

1.3、在小规模的程序设计中,面向过程的编程方法具有高效率,快速等等优点,但是随着程序规模的不断增大,通过简单的对过程的分割变得困难,所以产生了基于对象和面向对象的程序设计方法。

二、基于对象的设计方法

2.1、基于对象的设计方法把考虑问题的核心由过程转向了数据,过程依附于数据,在c++中,用户可以自定义类型,并且这种类型通过c++提供的各种设施可以让编译器同等对待。

例如我们定义了整数a,int a=2,a是编译器内置支持的数据类型,我们可以对a进行算数,移位,关系运算等操作,当我们把一个浮点数赋值给a的时候,编译器还会检查类型错误。我们现在把a看成是具有这些操作的对象,用户也可以定义自己的类型,编译器也会进行类型检查,不同的是我们自己定义的数据类型所具有的各种操作需要我们自己定义。

2.2、c++给我们提供创建自己的数据类型的能力,这样就很容易根据问题来构建和问题相对应的数据类型,并由此产生对象,这种能力在系统资源与问题之间搭起了桥梁,使程序更容易设计、维护。

三、定义自己的数据类型(类类型)

#include <stdio.h>
#include <stdlib.h>

/*
类类型不仅可以让我们把数据可以数据对应的操作捆绑在一起还可以提供以下机制
1、提供了一个作用域范围
2、可以对类作用域范围的类成员访问进行控制
3、其他见下文
*/
class person //定义了自己的数据类型
{
public:
void age(void)
{
printf("my age is %d\n",_age);
}
private:
int _age;
};

int main(void)
{
person me; //用自定义的数据类型产生对象
me.age();
system("pause");
return 0;
}


四、让类类型成为一等公民

用于自定义类型要想和内置类型具有同等的地位,必须需要做出各种处理。

4.1、类对象的初始化

在c语言中,为初始化的全局变量是类型相对应的初始值,例如整数是0,浮点数是0.0,c++对于类对象的初始化我们可以有更多的控制,因为类对象可以含有多个成员,所以c++利用构造函数对类对象进行初始化。

4.1.1、如果用户没有为类类型提供构造函数,那么c++将会提供一个默认的构造函数,随着对象所处作用域的不同,类成员的初始值也不一样。

#include <stdio.h>
#include <stdlib.h>

class person
{
public:
void age(void)
{
printf("my age is %d\n",_age);
}
private:
int _age;
};

person me; //在全局作用域范围的类对象成员被初始化为0

int main(void)
{
person you; //在栈中的类对象为随机值
person *him=new person(); //在堆中的类对象成员被初始化为0
me.age();
you.age();
him->age();
system("pause");
return 0;
}


4.1.2、默认函数赋予的类对象成员的初始值往往不能满足我们的需要,可以自定义构造函数,构造函数是可重载的,一旦用户提供构造函数,c++将不再提供默认构造函数。

#include <stdio.h>
#include <stdlib.h>

class person
{
public:
person(){_age=30;} //无参构造函数
person(int age){_age=age;}//带参构造函数
void age(void)
{
printf("my age is %d\n",_age);
}
private:
int _age;
};

int main(void)
{
person you;
you.age();
person me(28);
me.age();
system("pause");
return 0;
}


4.1.3、无参构造函数和有参构造函数解决了我们定义类对象时的类对象的初值问题,而拷贝构造函数可以使我们使类对象像用户对象一样的进行赋值,当我们没有定义类的拷贝构造函数时,相同类型对象之间的赋值会被简单的处理成位拷贝,而我们可能只是需要另一个对象的一部分,或者是需要进行深拷贝时就需要自己定义拷贝构造函数。

#include <stdio.h>
#include <stdlib.h>

class person
{
public:
person(int age=30){_age=age;}//带参构造函数
person(const person& other);//const 可选
person(const person* other);//指针类型也可以

void age(void)
{
printf("my age is %d\n",_age);
}
private:
int _age;
};

person::person(const person& other)
{
_age=other._age+1; //改变默认拷贝构造函数的行为
}

person::person(const person* other)
{
_age=other->_age - 1;
}

int main(void)
{
person you;
you.age();
person me(28);
me.age();
person him=you;
him.age();//31
person her=&you;
her.age();
system("pause");
return 0;
}


4.1.4、静态成员,const成员及其初始化

类类型的静态成员就是类作用域内的全局变量,而const成员和引用成员由于在成员被创立时就要确定其初值,所以他们的初始化需要成员初始化列表来完成。

可以理解为类对象的初始化分成两个步骤,开辟空间及对空间进行赋值,const和引用成员必须在开辟空间的步骤就要初始化,放到成员初始化列表里就可以达到这一目的。

#include <stdio.h>
#include <stdlib.h>

class person
{
public:
person(int age=30,const char* name="justsong"):_name(name){_age=age;}//带参构造函数,多个初始化列表用逗号分开
person(const person& other);//const 可选
static const char *_country;//静态变量也要受访问权限的限制

void age(void){	printf("my age is %d\n",_age); }
void country(void){ printf("%s\n",_country);}
void name(void){ printf("%s\n",_name);}
private:
int _age;
const char * _name; //需要利用成员初始化列表进行初始化
};

person::person(const person& other)
{
_age=other._age+1; //改变默认拷贝构造函数的行为
}

const char * person::_country="china"; //静态成员的初始化必须加上类型

int main(void)
{
person you;
you.age();
you.country();
you.name();
system("pause");
return 0;
}


4.1.5、至此我们的对象可以像内置类型对象一样进行类型检查,赋值操作,并且可以很好的进行初始化,通过操作符重载可以让内置的操作符作用于自定义类对象。

4.1.6、类类型的其他细节
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: