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;
}

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