类和对象(1)

定义的简单介绍: 类是对具有共同属性和行为的一类实物的抽象描述。 共同属性被描述为类中的数据成员,共同行为(操作)别描述为类中的成员函数。类跟结构类似,也是一种用户定义的类型。包括定义数据成员和定义函数成员(也成为方法)两个方面。使用数据成员来描述同类实物的属性,用函数成员来描述他们的行为。

消息是一个对象要求另一个对象实施某项操作的请求。是对象之间星湖联系的唯一途径。是驱动面向对象程序运转的源泉。

抽象,就是抽取问题本质的东西而忽略非本质的细节。

对象的特点:1、实例性。2、封装性。3、独立性。4、易维护性。

日期类的定义:

class Date
{
private:
	int year;
	int month;
	int day;
public:
	void SetDate(int y ,int m ,int d);
	int IsLeapYear();
	void Print();
};

void Date::SetDate(int y ,int m ,int d)
{
	year =y;
	month=m;
	day=d;
}
int Date::IsLeapYear()
{
	return (year%4==0&&year%100!=0)||(year%400==0);
}
void Date::Print()
{
	cout << year <<"." << month << "." << day << endl;
}


这里实现类成员使用函数时候,使用了作用域运算符(::)来标识 函数所属的类。如果不使用该标识符。要用如下方式定义类:


class Date
{
private:
	int year;
	int month;
	int day;
public:
	void SetDate(int y ,int m ,int d)
	{year =y;month=m;day=d;}
	
	int IsLeapYear()
	{return (year%4==0&&year%100!=0)||(year%400==0);}

	void Print()
	{cout << year <<"." << month << "." << day << endl;}
};

若成员函数的实现写在类体内,这些函数都将自动的成为 内联函数。(若在类声明外定义内联的成员函数,只需要在类实现中定义函数是显示的使用关键字inline即可)。

 对象是类的实际变量,也称为类的实例。可以直接定义对象,格式:

class Date

{

public:

void SetDate(int y ,int m,int d);

int IsLeapYear();

void Print();

private:

int year;

int month;

int day;

}da1,da2;

也可以声明类之后在定义对象,定义的格式与一般变量的定义格式形同。

Date da1,da2;


访问对象成员:

da1.year=2007; //访问数据成员

da2.Print(); //访问成员函数

对于指针类型的对象,使用--->操作符。

Date *pd;

pd-->year=2007;

pd-->Print();


简单例子说明如何定义类和使用对象。

#include <iostream>
using namespace std;
//类定义
class Date
{
private:
	int year;
	int month;
	int day;
public:
	Date(int y,int m,int d);//构造函数
	Date();//默认构造函数
	void SetDate(int y,int m,int d);
	int IsLeapYear();
	void Print();
	~Date();
};
//实现部分
 Date::Date(int y,int m,int d)
 {
	 cout << "calling constructor to set";
	 year=y;
	 month=m;
	 day=d;
	 cout << year << "." << month << "."<< day <<endl;

 }
 Date::Date()
 {
	 cout << "calling default constructor to set";
	 year=1997;
	 month=7;
	 day=1;
	 cout << year << "." << month << "." << day << endl;
 }
 void Date::SetDate(int y,int m,int d)
 {
	 cout << "calling member function to set";
	 year=y;
	 month=m;
	 day=d;
	 cout << year << "." << month << "." << day << endl;
 }
 int Date::IsLeapYear()
 {
	 return (year%4==0&&year%100!=0)||(year%400==0);
 }
 void Date::Print()
 {
	 cout << year << "." << month << "." << day << endl;
 }
 Date::~Date()
 {
	 cout << "calling destructor to clear";
	 cout << year << "." << month << "." << day << endl;
 }

 int main()
 {
	 Date da1,da2; //调用默认构造函数 1997.7.1  1997.7.1
	 Date da3(2000,1,1);//调用构造函数 2000.1.1
	 Date *pd;

	 da1.SetDate(2008,8,8); //调用成员函数初始化对象
	 da2=da1; //对象之间赋值
	 pd=&da2;
	 pd->SetDate(2006,6,6);

	 cout << "For object da1:" << endl;
	 cout << "Date:";
	 da1.Print();
	 if(da1.IsLeapYear())
		 cout << "this year is leap year." << endl;
	 else
		 cout << "this year is not a leap year." << endl;

	 cout << "for object da2:" << endl;
	 cout << "Date:";
	 da2.Print();
	 if(da2.IsLeapYear())
		 cout << "this year is leap year." << endl;
	 else
		 cout << "this year is not a leap year." << endl;

	 cout << "for object da3:" << endl;
	 cout << "Date:";
	 da3.Print();
	 if(da3.IsLeapYear())
		 cout << "this year is leap year." << endl;
	 else
		 cout << "this year is not a leap year." << endl;

	 return 0;

 }

运行结果:

重构函数:

c++允许重构,满足重构的定义,可以定义任意多个构造函数。默认的构造函数和一般的构造函数就促成了重构构造函数。除此之外还可以定义不同的构造函数,以便使对象初始化时有更多选择。
例如可以给构造函数传递一个日期的字符串,有构造函数来解释日期并初始化成员变量。

class Date
{
public:
	Date();
	Date(int y,int m,int d);
	Date(char* da);
	Date(char *da,int y);

	void SetDate(int y,int m,int d);
	int IsleapYear();
	void Print();
	~Date();

private:
	int year;
	int month;
	int day;
};
//可以用如下方法定义类对象
Date da1;//调用的默认构造函数
Date da2(2000,1,1);
Date da3("2007,5,8");
Date da4("6.8",2006);

拷贝构造函数

它可以根据已存在的对象简历一个新的对象。它用于初始化而不是常规的赋值过程。拷贝构造函数原型:
Class Name(const  ClassName &);
BadClass(const  BadClass &);

头文件:.h
#include<iostream>
using namespace std;

#ifndef BADCLASS_H_
#define BADCLASS_H_

class BadClass
{
private:
	char* str;
	int len;
public:
	BadClass(const char* s);
	BadClass();
	~BadClass();
	void Print();
	BadClass(const BadClass & );
	
};
#endif

.cpp
#include<iostream>
#include<cstring >
#include "BadClass.h"
using namespace std;

BadClass::BadClass(const char* s)
{
	len=strlen(s);
	str=new char[len+1];
	strcpy(str,s);
	cout << "\"" << str << "\"object created." << endl;
}

BadClass::BadClass()
{
	len=8;
	str=new char[8];
	strcpy(str,"Default");
	cout << "\"" << str << "\"object created." << endl;
}

BadClass::~BadClass()
{
	cout << "\"" << str << "\" object deleted." << endl;
}

void BadClass::Print()
{
	cout << str << endl;
}

BadClass::BadClass(const BadClass & bc)//拷贝构造函数
{
	len=bc.len;
	str=new char[len+1];
	strcpy(str,bc.str);
	cout << str << ":Copy constructor is called." << endl;
}

.cpp main()
#include<iostream>
using namespace std;
#include"BadClass.h"

void call1(BadClass &);
void call2(BadClass);

int main()
{
	BadClass news("The primary Project is complete");
	BadClass sports("Rocket is on air");

	call1(news);
	call2(news);//调用拷贝构造函数,当函数按值传递对象或者返回对象时候,由于要生成对象的一个副本,因此都会调用拷贝构造函数

	cout << "Initialize one object to another:" << endl;
	BadClass spnews=sports;//调用拷贝构造函数,创建一个新的对象并将初始化为现有对象时,会调用拷贝构造函数
	spnews.Print();
	cout << "End of main()" << endl;
	
	return 0;
}

void call1(BadClass &rsb)
{
	cout << "String passed by reference:";//字符串通过引用传递
	rsb.Print();
}

void call2(BadClass sb)
{
	cout<< "String passed by value:"; //字符串值传递
	sb.Print();
}

结果:



若没有拷贝构造函数的话,采用默认的spnews.str=sports.str; 这样两个对象的str都指向了同一个内存。在程序结束时候,调用对象的析构函数释放动态内存时候,spnews和sports的析构函数都会调用,导致同一内存区域被释放两次,这会导致不确定的结果,因此会使程序出错。

对象数组 

每个元素都是类对象的数组。
初始化:
Cow farm1[3]=
{
Cow("nano",350),
Cow("boffo",405),
Cow("fleep",380),
} ;
例子:

#include<iostream>
using namespace std;

class Cow
{
private:
	char name[20];
	double weight;
public:
	Cow();
	Cow(char *nm,double wt);
	void ShowCow();
};

Cow::Cow()
{
	strcpy(name,"default");
	weight=380;
}

Cow::Cow(char *nm,double wt)
{
	strcpy(name,nm);
	weight=wt;
}

void Cow::ShowCow()
{
	cout <<"this cow is" << name << ",its weight is" << weight << "." << endl;
}

int main()
{
	Cow farm[4]=
	{
		Cow("Nano",350),
		Cow("Boffo",405),
		Cow("Fleep",380),
	};
	int i;
	for(i=0;i<4;i++)
	{
		cout << "For No." << i+1 << "cow:" << endl;
		farm[i].ShowCow();
	}
	return 0;
}
结果是:

告一段落,等会继续学习:对象指针,向函数传递对象,静态成员,友元。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值