WHCSRL 技术网

C++起步(二)

C++程序到C程序的翻译

早期实际上C++的编译,先翻译为C,再拿C的编译器去编译

class Car{
	public:
		int price;
		void SetPrice(int p);
}; 
void Car::SetPrice(int p){
	price=p;
}
int main(){
 	Car new_car;
 	new_car.SetPrice(2000);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

翻译为C:

struct Car{
	int price;
};
//普通成员函数翻译为全局函数,且多一个指针参数 
void SetPrice(struct Car *this,int p){
	this->price=p;
}
int main(){
	struct Car new_car;
	// 因为C没有对象的概念
	SetPrice(&new_car,2000);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

this 指针

可以用在成员函数里面
指向成员函数所作用的对象

Complex AddOne(){
	this->real++;		// 等价于 real++ 
	this->print();		// 等价于 print() 
	return *this;
}
  • 1
  • 2
  • 3
  • 4
  • 5
class A{
 	public:
 		int i;
 		void Hello(){
 			cout<<"hello"<<endl;
		 }
};	// 编译时 会翻译成 void Hello(A *this){cout<<"hello"<<endl;} 
int main(){
	A*p=NULL;
	p->Hello();		// 编译时 会翻译成 Hello(p);
}
所以可以成功运行 输出Hello
但如果函数里是: cout<<i<<"hello"<<endl; 就会出错了
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

静态成员函数中不能使用 this 指针。因为静态成员函数并不具体作用与某个对象。

静态成员

普通成员变量每个对象有各自的一份,静态成员变量一共就一份,为所有对象共享。
别的类的对象是无法访问这个静态成员变量的。

sizeof运算符不会计算静态成员变量,结构体里的也一样
class Cmyclass{
	int n;
	static int s;
};
int main(){
	cout<<sizeof(Cmyclass);		// 输出 4
} 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

普通成员函数必须具体作用于某个对象,静态成员函数并不具体作用于某个对象。
静态成员不需要通过对象就能访问。Cmyclass::s
静态成员变量本质上是全局变量,哪怕一个对象都不存在,类的静态成员变量也存在。
静态成员函数本质上是全局函数。
静态成员函数中,不能访问非静态成员变量和非静态成员函数。

成员对象和封闭类

成员对象:这个成员变量是其他类的一个对象
封闭类:成员变量里有成员对象的这么一个类

对封闭类的构造函数,一般要给一个初始化列表

class CCar{
	private:
		int price;
		CTyre tyre;
		CEngine engine;
	public:
		CCar(int p,int tr,int tw);
};
CCar::CCar(int p,int tr,int tw):price(p),tyre(tr,tw){
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

封闭类对象生成时,里面的成员对象也会生成,会引发一系列的构造函数
封闭类对象生成时,先执行所有成员对象的构造函数,再去执行封闭类的构造函数。

常量对象,常量成员函数

class A{
	int value;
};
const A obj;
obj.value=100;		// wrong
常量对象 也不可以执行非常量成员函数
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
常量成员函数执行期间不能修改所作用的对象,不能修改成员变量的值(静态成员变量除外)
也不能调用同类的非常量成员函数(静态成员函数除外)
class Sample{
	public:
		int value;
		void GetValue() const;	// 常量成员函数 
		void func(){
		};
		Sample(){
		};
};
void Sample::GetValue() const{
	value=0;	// wrong
	func();		// wrong
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

友元

友元函数:一个类的友元函数可以访问这个类的私有成员
友元函数不是这个类的成员函数,是这个类的朋友。

class CCar;	// 声明 CCar类,方便CDriver类里使用 
class CDriver{
	public:
		void ModifyCar(CCar *p);
}; 
class CCar{
	private:
		int price;
	// 对 CCar 类的友元函数进行声明 
	friend int Most_Expensive_Car(CCar cars[],int total);
	friend void CDriver::ModifyCar(CCar *p);
};
// CDriver类的成员函数 
void CDriver::ModifyCar(CCar *p){
	p->price+=1000;		// 友元函数里可直接访问 私有变量 
}
// 普通的全局函数 
int Most_Expensive_Car(CCar cars[],int total){
	int tem=-1;
	for(int i=0;i<total;i++){
		if(cars[i].price>tem){
			tem=cars[i].price;		// 直接访问私有成员 
		}
	}
	return tem;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

友元类:如果A是B的友元类,则A的成员函数 可以访问 B类的私有成员。

class CCar{
	private:
		int price;
	// 声明 CCar的友元类 
	friend class CDriver;
}; 
class CDriver{
	public:
		CCar myCar;	// 成员对象 
		void ModifyCar(){
			myCar.price+=1000;		// OK 
		}
};
// 如果 CDriver 不是 CCar 的友元,尽管定义了myCar,也不能 访问其私有成员。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
推荐阅读