一 静态成员变量
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 ;
}