1. 程式人生 > >C++類的其他成員變數及屬性

C++類的其他成員變數及屬性

一 靜態成員變數
1 把一個類的成員說明為 static 時,這個類無論有多少個物件被建立,
這些物件共享這個 static 成員.
2 靜態成員區域性於類,它不是物件成員

#include<iostream> 
using namespace std; 
class  counter 
{     
  static  int  num ; //宣告與定義靜態資料成員 
  public : 
  void  setnum ( int i ) { num = i ; } //成員函式訪問靜態資料成員 
  void  shownum() { cout << num << '\t' ; } 
} ; 

int  counter :: num = 0 ;//宣告與定義靜態資料成員
void main () 
{
    counter  a , b ; 
    a.shownum() ; //呼叫成員函式訪問私有靜態資料成員 
    b.shownum() ; 
    a.setnum(10) ; 
    a.shownum() ; 
    b.shownum() ; 
}

二 靜態成員函式
1 靜態成員函式提供不依賴於類資料結構的共同操作,它沒有this指標
2 在類外呼叫靜態成員函式用 “類名 :: ”作限定詞,或通過物件呼叫。
3 靜態成員函式中,不能使用普通成員變數,不能使用普通成員函式。
靜態成員變數屬於整個類的,分不清楚,是那個具體物件的屬性。

#include <iostream>
using namespace std;

class BB
{
public:
void printC()
{
    cout<<"c:"<<c<<endl;
}
void AddC()
{
    c = c + 1;
}
static void getC() //靜態成員函式 
{
    cout<<"c:"<<c<<endl;
    //請在靜態成員函式中,能呼叫 普通成員屬性  或者 普通成員函式嗎?
    cout<<"a:"<<a<<endl; //error C2597: 對非靜態成員“BB::a”的非法引用
}
private:
int a; 
int b;
static int c; //靜態成員變數
};

//靜態函式中 不能使用 普通成員變數 普通成員函式 ..
int BB::c = 10;
void main()
{
BB b1, b2, b3;
b1.printC(); //10
b2.AddC(); //11
b3.printC(); //11
//靜態成員函式的呼叫方法
b3.getC(); //用物件.
BB::getC();//類::
cout<<"hello..."<<endl;
system("pause");
return ;
}

三 C++面向物件模型初探
1 在c語言中,“資料”和“處理資料的操作(函式)”是分開來宣告的,也就是說,語言本身並沒有支援“資料和函式”之間的關聯性。
在c++中,通過抽象資料型別(abstract data type,ADT),在類中定義資料和函式,來實現資料和函式直接的繫結。
2 在C++類中有兩種成員資料:static、nonstatic;
三種成員函式:static、nonstatic、virtual。
3 總結
1)C++類物件中的成員變數和成員函式是分開儲存的。C語言中的記憶體四區模型仍然有效!
2)C++中類的普通成員函式都隱式包含一個指向當前物件的this指標;
3) 靜態成員函式、成員變數屬於類
4 )靜態成員函式不包含指向具體物件的指標

,普通成員函式包含一個指向具體物件的指標

#include <iostream>
using namespace std;
class Test
{
public:
Test(int a, int b) //---> Test(Test *this, int a, int b)
{
    this->a = a;
    this-> b = b;   
}
void printT()
{
    cout<<"a: " <<a <<endl;
    cout<< "b: " << this->b <<endl;
}
//1 const 寫的什麼位置 沒有關係 
//2 const修飾的是誰?
// 2-1const修飾的是形參a 不是
// 2-2const修飾的是屬性this->a  this->b 
// 2-3 const修飾的是this指標所指向的記憶體空間, 修飾的是this指標
 void  OpVar( int a, int b) const   //==>void  OpVar(const Test *this, int a, int b)  
     //==>void  OpVar( const Test *const this, int a, int b)  
{
    a = 100;
    //this->a = 100;
    //this->b = 200;
    //this = 0x11;
    //cout<<"a: " <<a <<endl;
    cout<< "b: " << this->b <<endl;
}
private:
int a;
int b;
};

void main()
{

int *m_space = new int[0];
if (m_space == NULL)
{
    return ;
}

Test t1(1, 2);
t1.printT();// ===> printT(&t1)
cout<<"hello..."<<endl;
system("pause");
return ;
}

四 全域性函式與成員函式
1 把全域性函式轉化成成員函式,通過this指標隱藏左運算元
Test add(Test &t1, Test &t2)===》Test add(Test &t2)
2 把成員函式轉換成全域性函式,多了一個引數
void printAB()===》void printAB(Test *pthis)

五 友元
1 友元函式
1)友元函式不是類的成員函式,是類的“好朋友”,可以修改類的私有屬性。
2)特點:
a) 一般友元函式要的引數要包含是哪個類的物件指標或物件引用。
b) 友員類通常設計為一種對資料操作或類之間傳遞訊息的輔助類。

2 友元類
1)若B類是A類的友員類,則B類的所有成員函式都是A類的友員函式;
2)友員類通常設計為一種對資料操作或類之間傳遞訊息的輔助類 ;

#include <iostream>
using namespace std;
class A
{
public:
friend class B;//B類 是 A的好朋友 ,在B中可以訪問A類的私有成員 私有函式
//1 宣告的位置 和 public private沒有關係
friend void modifyA(A *pA, int _a); //2 函式modifyA 是 類A的好朋友
A(int a=0, int b=0)
{
    this->a = a;
    this->b = b;
}
int getA()
{
    return this->a;
}
private:
int a;
int b;
};
void modifyA(A *pA, int _a)
{
//pA->a = 100;
pA->a = _a;

class B
{
public:
void Set(int a)
{
    Aobject.a = a;
}
void printB()
{
    cout<<Aobject.a <<endl;
}
private:
A Aobject;
};
void main()
{
B b1;
b1.Set(300);
b1.printB();
system("pause");
}
void main2101()
{

A a1(1, 2);
cout<< a1.getA()<<endl;
modifyA(&a1, 300);
cout<< a1.getA()<<endl;


cout<<"hello..."<<endl;
system("pause");
return ;
}

六 運算子過載
1 運算子過載的本質是函式呼叫
2運算子過載的限制:a)不改變運算子的優先順序b)不改變運算子的結核性c)不改變運算子需要的運算元d)不創造新的運算子
3 運算子過載程式設計基礎
a)運算子函式是一種特殊的成員函式或友元函式
b)成員函式的語法形式:
型別 類名 ::operator op(引數){}
4全域性函式、類成員函式方法實現運算子過載步驟
1)要承認操作符過載是一個函式,寫出函式名稱
2)根據運算元,寫出函式引數
3)根據業務,完善函式返回值(看函式是返回引用 還是指標 元素),及實現函式業務

#include <iostream>
using namespace std;
class Complex
{
private:
int a;
int b;
//全域性函式 過載+運算子
friend Complex operator+(Complex &c1, Complex &c2);
//過載 前置++
friend Complex& operator++(Complex &c1);
//後置++
friend Complex operator++(Complex &c1, int);//int是佔位符。主要是實現引數過載

public:
Complex(int a=0, int b=0)
{
    this->a = a;
    this->b = b;
}
void printCom()
{
    cout<<a<<" + " << b << "i" <<endl;
}
public:

//成員函式法 實現 -運算子過載
 Complex operator-(Complex &c2)
{
    Complex tmp(this->a - c2.a, this->b - c2.b);
    return tmp;
}

 //前置--
Complex& operator--()
{
    this->a --;
    this->b --;
    return *this;
}

//後置--
Complex operator--(int)
{
    Complex tmp = *this;
    this->a--;
    this->b--;
    return tmp;
}
};

//全域性函式法 實現 + 運算子過載
Complex operator+(Complex &c1, Complex &c2)
{
Complex tmp(c1.a + c2.a, c1.b + c2.b);//生成匿名物件
return tmp;
}

//前置++
Complex& operator++(Complex &c1)
{
c1.a++;
c1.b++;
return c1;
}

//後置++
Complex operator++(Complex &c1, int)
{
//先使用 在讓c1加加
Complex tmp = c1;
//return c1;
c1.a ++;
c1.b ++;
return tmp;
}

void main()
{
Complex c1(1, 2), c2(3, 4);


//1 全域性函式法 實現 + 運算子過載
// Complex operator+(Complex &c1, Complex &c2);
Complex c3 = c1 + c2;
c3.printCom();

//2 成員函式法 實現 -運算子過載
//如果是成員函式則呼叫形式如:c1.operator-(c2);//
//Complex operator-(Complex &c2)
Complex c4 = c1 - c2;
c4.printCom();

//前置++操作符 用全域性函式實現
++c1;
c1.printCom();

//前置--操作符 成員函式方法
--c1;
c1.printCom();
//Complex& operator++(Complex &c1)
//c1.operator--();

//後置++操作符 用全域性函式實現
c1++;
c1.printCom();

//後置--操作符 用成員函式實現
c1--;
c1.printCom();
//c1.operator--()

cout<<"hello..."<<endl;
system("pause");
return ;
}