C++学习笔记之"类和对象I"


成员函数的实现(函数定义)都写在类体中,与一般的函数定义一样。
class TDate
{
public:
void SetDate(int y,int m,int d)
{
year=y;
month=m;
day=d;
}
void Print()
{
cout<<year<<"."<<month<<"."<<day<<endl;
}
private:
int year,month,day;
}
成员函数在类体中声明,实现在类体外且在声明之后 例:
class TDate
{
public:
void SetDate(int y,int m,int d);
void Print();
private:
int year,month,day;
}
void TDate::SetDate(int y,int m,int d)
{
year=y;
month=m;
day=d;
}
void TDate::Print()
{
cout<<year<<"."<<month<<"."<<day<<endl;
}
::为作用域运算符,用来标识某个成员函数是属于哪个类的。
注意:
1.在类体中不允许对所定义的数据成员进行初始化,例:
class TDate
{
public:
.
.
.
private:
int year(1989),month(6),day(4);
}语法错误,编译无法通过。
2.数据成员的类型可以为:int、float、char、数组、指针和引用、对象(自身类的对象不可以,自身类的指针或引用可以),一个类的对象作为某个类的成员时,如果类的定义在后,要提前说明。
class N;
class M
{
public:
.
.
.
private:
class N n;
}
class N
{
.
.
.
}
3.一般地,在类体内先说明公有成员,后说明私有成员。说明数据成员时,按数据类型的大小,由小到大说明。
4.经常习惯性的将类定义的说明部分或整个定义部分(包含实现部分)放到头文件里面,后面引用比较方便。

对象的定义
TDate date1,*Pdate,data[32],&rdate=date1;//一般对象名,指向对象的指针,对象数组,对象的引用(它是date1的别名)
对象成员的表示方法
date1的成员可表示为:
date1.year//数据成员
date1.SetDate(int y,int m,int d)//成员函数
指针Pdate的成员可表示为:
Pdate->year//数据成员
date1->SetDate(int y,int m,int d)//成员函数

(*Pdate).year
(*PDate).SetDate(int y,int m,int d)
引用对象的成员表示和一般对象的成员表示相同。
#include <iostream>
#include <tdate.h>
using namespace std;
void main()
{
 TDate date1,date2;
 date1.SetDate(1989,6,4);
 date2.SetDate(2009,7,5);
 date1.Print();
 date2.Print();
 double q;
 std::cin>>q;
}

对象的初始化
class TDate
{
public:
 TDate(int y,int m,int d);//构造函数(成员函数) 函数体可写在类体内,也可写在类体外
//可以有若干个参数,可以设置参数的缺省值,因此可以重载
//不能直接调,创建对象时系统会自动调用
//没有显式定义构造函数,将使用缺省构造函数                            
 ~TDate();//析构函数(成员函数) 函数体可写在类体内,也可写在类体外
//不指定数据类型,无参数,无法重载
//析构函数自动调用的情形:(1)定义在一个函数体内的对象,当这个函数结束时 (2) 一个对象使用new运算符动态创建,使用delete运算符释放它时
//没有显式定义析构函数,将使用缺省析构函数  
void Print();
private:
int year,month,day;
};
TDate::TDate(int y, int m, int d)
{
 yaer=y;
 month=m;
 day=d;
 cout<<"Constructor called./n";
}
TDate::~TDate()
{
 cout<<"Desstructor called./n";
}
void TDate::Print()
{
cout<<year<<"."<<month<<"."<<day<<endl;
}
注意:类中的函数的函数体要么都写在类体内,要么都写在类体外,规范编码。
构造函数、析构函数的应用
void main()
{
TDate date1(1999,6,4),date2(2009,7,5); 
//TDate date1,date2; 缺省构造函数
    cout<<"19900604 Event is ";
 date1.Print();
 cout<<"20090705 Event is ";
 date2.Print();
}

拷贝初始化构造函数
是一种特殊的构造函数,作用是用一个已知的对象来初始化一个被创建的同类的对象。
初始化的过程是将已知对象的数据成员的值拷贝给正在创建的另一个同类的对象。
class TDate1
{
public:
 TDate1(int y,int m,int d)
  {
 year=y;
 month=m;
 day=d;
 cout<<"Constructor called./n";
}
 ~TDate1()
 {
 cout<<"Desstructor called./n";
}
//函数名与类名相同,参数为引用同类的一个对象,如果无显示定义拷贝初始化函数,编译系统会自动生成一个,作为该类的公有成员
TDate1(TDate1 &p)
{
 year=p.year;
 month=p.month;
 day=p.day;
 cout<<"Copy_initialization Constructor called./n";
}
void Print()
{
cout<<year<<"."<<month<<"."<<day<<endl;
}
public:
int year,month,day;
};
调用拷贝初始化函数(3种情况)
TDate1 f(TDate1 Q);
void main()
{
TDate1 date1(1989,6,4),date2(2009,7,5);
 TDate1 date3(date1);//情况1:明确表示由一个对象初始化另一个对象
 date2 = f(date3);//情况2:对象作为函数实参传递给函数形参
 
    cout<<"6.4 Event is ";
 date1.Print();
 
 cout<<"date3's data number is ";
    date3.Print();

 cout<<"date2's data number is ";
 date2.Print();
}
TDate1 f(TDate1 Q)
{
 cout<<"ok/n";
 int year,month,day;
 year=Q.year+1;
 month=Q.month+1;
 day=Q.day+1;
 TDate1 R(year,month,day);
 return R;//情况3:对象作为函数返回值
}

成员函数的特性
成员函数分为内联函数和外联函数
内联函数的函数体放在类体内,编译过程和宏定义一样采用替换原则,执行效率高。一定要在调用之前进行定义且内联函数无法递归调用
外联函数说明在类体内定义在类题外,函数体在类的实现部分
在外联函数的函数头前面加上inline就可以变成外联函数

静态成员
解决数据的共享问题
实现多个对象之间的数据共享,可以不使用全局对象,而是用静态的数据成员
它是类的所用对象共享的成员,而不是某个对象的成员,节省内存
初始化时注意:
在类体外初始化,前面不用加static
不加该成员的访问控制符private、public等
用作用域运算符来表明它所属的类,它为类的成员,而非对象的
静态数据成员
class MyClass
{
public:
 MyClass(int a,int b);
 void GetNumber();
 void GetSum();
private:
 int A,B;
 static int Sum;

};
int MyClass::Sum = 0;//在类体外初始化,前面不用加static,不加该成员的访问控制符private、public等
MyClass::MyClass(int a,int b)
{
 A=a;
 B=b;
 Sum+=A+B;
}
void MyClass::GetNumber()
{
 std::cout<<"A="<<A<<",B="<<B<<std::endl;
}
void MyClass::GetSum()
{
 std::cout<<"sum="<<Sum<<std::endl;
}
void main()
{
MyClass M(3,7),N(14,9);
 M.GetNumber();
 N.GetNumber();

 M.GetSum();
 N.GetSum();
}
}
静态成员函数
class M
{
public:
 M(int a){A=a,B+=a;}
 static void f1(M m);
private: int A;
 static int B;
};
//在静态成员函数的实现中可以引用类中的静态成员,必须经过对象来引用类中说明的非静态成员
void M::f1(M m)
{
 std::cout<<"A="<<m.A<<",B="<<B<<std::endl;
}
int M::B=0;
void main()
{
M P(5),Q(10);
//静态成员函数的调用
M::f1(P);
M::f1(Q);
}

友元
是一种定义在类外部的普通函数,需要在类体内进行说明,  前面加friend
非成员函数但能访问类的私有成员
提高了程序运行效率,但破坏了类的封装性和隐藏性
友元函数
class Point
{
public:
 Point(double xx,double yy){x=xx;y=yy;}
 void Getxy();
 friend double Distance(Point &a,Point &b);
private:
 double x,y;
};
void Point::Getxy()
{
std::cout<<"x="<<x<<",y="<<y<<std::endl;
}
double Distance(Point &a,Point &b)
{
//通过对象引用类的私有成员
 double dx=a.x-b.x;
 double dy=a.y-b.y;
 return sqrt(dx*dx+dy*dy);
}
void main()
{
Point p1(3.0,4.0),p2(6.0,8.0);
p1.Getxy();
p2.Getxy();
double d=Distance(p1,p2);//直接调用友元函数
std::cout<<"Distance is "<<d;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章