标签:技术分享 const mod -- 常量 double mos 执行 文件
class CRectangle { public: int w, h; void Init( int w_, int h_ ) { w = w_; h = h_; } int Area() { return w * h; } int Perimeter() { return 2 * ( w + h ); } }; //必须有分号
int main() { int w, h; CRectangle r; //r是一个对象 cin >> w >> h; r.Init(w, h); cout << r.Area() << endl << r. Perimeter(); return 0; }
类定义的变量 -> 类的实例 -> “对象”
对象的大小 = 所有成员变量的大小之和。E.g. CRectangle类的对象, sizeof(CRectangle) = 8
对象之间可以用 ‘=’ 进行赋值
CRectangle r1, r2; r1.w = 5; r2.Init(3,4);
用法2: 指针->成员名
CRectangle r1, r2; CRectangle * p1 = & r1; CRectangle * p2 = & r2; p1->w = 5; p2->Init(3,4); //Init作用在p2指向的对象上
用法3: 引用名.成员名
CRectangle r2; CRectangle & rr = r2; rr.w = 5; rr.Init(3,4); //rr的值变了,r2的值也变
class CRectangle { public: int w, h; int Area(); //成员函数仅在此处声明 int Perimeter() ; void Init( int w_, int h_ ); };
int CRectangle::Area() { return w * h; } int CRectangle::Perimeter() { return 2 * ( w + h ); } void CRectangle::Init( int w, int h) { this->w = w; this->h = h;
}
private: 指定私有成员, 只能在成员函数内被访问
public: 指定公有成员, 可以在任何地方被访问
protected:指定保护成员
缺省为私有成员!
对象成员的访问权限:
类的成员函数内部, 可以访问:当前对象的全部属性, 函数; 同类其它对象的全部属性, 函数
类的成员函数以外的地方只能够访问该类对象的公有成员
class CEmployee { private: char szName[30]; //名字 public : int salary; //工资 void setName(char * name); void getName(char * name); void averageSalary(CEmployee e1,CEmployee e2); }; void CEmployee::setName( char * name) { strcpy( szName, name); //ok } void CEmployee::getName( char * name) { strcpy( name, szName); //ok } void CEmployee::averageSalary(CEmployee e1,CEmployee e2){ salary = (e1.salary + e2.salary )/2; } int main(){ CEmployee e; strcpy(e.szName,"Tom1234567889"); //编译错, 不能访问私有成员 e.setName( "Tom"); // ok e.salary = 5000; //ok return 0; }
设置私有成员的目的:强制对成员变量的访问一定要通过成员函数进行
设置私有成员的机制 -- 隐藏
成员函数的一种:
class Complex { private : double real, imag; public: void Set( double r, double i); }; //编译器自动生成默认构造函数 Complex c1; //默认构造函数被调用 Complex * pc = new Complex; //默认构造函数被调用
class Complex { private : double real, imag; public: Complex( double r, double i = 0); }; Complex::Complex( double r, double i) { real = r; imag = i; } Complex c1; // error, 缺少构造函数的参数 Complex * pc = new Complex; // error, 没有参数 Complex c1(2); // OK Complex c1(2,4), c2(3,5); Complex * pc = new Complex(3,4);
class Complex { private : double real, imag; public: void Set( double r, double i ); Complex(double r, double i ); Complex (double r ); Complex (Complex c1, Complex c2); }; Complex::Complex(double r, double i) { real = r; imag = i; } Complex::Complex(double r){ real = r; imag = 0; } Complex::Complex (Complex c1, Complex c2){ real = c1.real+c2.real; imag = c1.imag+c2.imag; } Complex c1(3) , c2(1,0), c3(c1,c2);
构造函数在数组中使用
class CSample { int x; public: CSample() { cout << "Constructor 1 Called" << endl; } CSample(int n) { x = n; cout << "Constructor 2 Called" << endl; } }; int main(){ CSample array1[2]; cout << "step1"<<endl; CSample array2[2] = {4,5}; cout << "step2"<<endl; CSample array3[2] = {3}; cout << "step3"<<endl; CSample * array4 = new CSample[2]; delete []array4; return 0; }
输出: Constructor 1 Called Constructor 1 Called step1 Constructor 2 Called Constructor 2 Called step2 Constructor 2 Called Constructor 1 Called step3 Constructor 1 Called Constructor 1 Called
class Test { public: Test( int n) { } //(1) Test( int n, int m) { } //(2) Test() { } //(3) }; Test array1[3] = { 1, Test(1,2) }; // 三个元素分别用(1),(2),(3)初始化 Test array2[3] = { Test(2,3), Test(1,2) , 1}; // 三个元素分别用(2),(2),(1)初始化 Test * pArray[3] = { new Test(4), new Test(1,2) }; //两个元素分别用(1),(2) 初始化
#include <iostream> using namespace std; class Location { private : int x, y; public: void init( int x = 0 , int y = 0 ); void valueX( int val ) { x = val ; } int valueX() { return x; } }; void Location::init( int X, int Y){ x = X; y = Y; } int main() { Location A; A.init(5); A.valueX(5); cout << A.valueX(); return 0; }
class Complex { public : double real,imag; Complex(){ } Complex( const Complex & c ) { real = c.real; imag = c.imag; cout << “Copy Constructor called”; } }; Complex c1; Complex c2(c1);//调用自己定义的复制构造函数,输出 Copy Constructor called
复制构造函数起作用的三种情况
1)当用一个对象去初始化同类的另一个对象时。
2)如果某函数有一个参数是类 A 的对象, 那么该函数被调用时,类A的复制构造函数将被调用。
3) 如果函数的返回值是类A的对象时,则函数返回时,A的复制构造函数被调用.
目的:实现类型的自动转换
特点:只有一个参数,不是复制构造函数
当使用类型转换构造函数的时候,编译器会自动调用这个转换构造函数,建立一个临时对象/临时变量。
class Complex { public: double real, imag; Complex( int i ) { //类型转换构造函数 cout << “IntConstructor called” << endl; real = i; imag = 0; } Complex( double r, double i ){ real = r; imag = i; } }; int main () { Complex c1(7, 8); Complex c2 = 12; c1 = 9; // 9被自动转换成一个临时Complex对象 cout << c1.real << "," << c1.imag << endl; return 0; }
成员函数的一种
定义了析构函数, 则编译器不生成缺省析构函数
// 对象数组生命期结束时, 对象数组的每个元素的析构函数都会被调用 class Ctest { public: ~Ctest() { cout<< "destructor called" << endl; } }; int main () { Ctest array[2]; cout << "End Main" << endl; return 0; }
delete 运算导致析构函数调用 Ctest * pTest; pTest = new Ctest; //构造函数调用 delete pTest; //析构函数调用 ------------------------------------------------------------------ pTest = new Ctest[3]; //构造函数调用3次 delete [] pTest; //析构函数调用3次
构造函数和析构函数 调用时机的例题
class Demo { int id; public: Demo( int i ){ id = i; cout << “id=” << id << “ Constructed” << endl; } ~Demo(){ cout << “id=” << id << “ Destructed” << endl; } }; 输出: Demo d1(1); id=1 Constructed void Func(){ id=4 Constructed static Demo d2(2); id=6 Constructed Demo d3(3); id=6 Destructed cout << “Func” << endl; main } id=5 Constructed int main (){ id=5 Destructed Demo d4(4); id=2 Constructed d4 = 6; id=3 Constructed cout << “main” << endl; Func { Demo d5(5); } id=3 Destructed Func(); main ends cout << “main ends” << endl; id=6 Destructed return 0; id=2 Destructed } id=1 Destructed
静态成员:在说明前面加了static关键字的成员。
class CRectangle { private: int w, h; static int nTotalArea; //静态成员变量 static int nTotalNumber; public: CRectangle(int w_,int h_); ~CRectangle(); static void PrintTotal(); //静态成员函数 };
普通成员变量每个对象有各自的一份,而静态成员变量一共就一份,为所有对象共享。
class CRectangle { private: int w, h; static int nTotalArea; static int nTotalNumber; public: CRectangle(int w_,int h_); ~CRectangle(); static void PrintTotal(); }; CRectangle::CRectangle(int w_,int h_) { w = w_; h = h_; nTotalNumber ++; nTotalArea += w * h; }
CRectangle :: CRectangle(CRectangle & r ) {
w = r.w; h = r.h; nTotalNumber ++; nTotalArea += w * h;
}
CRectangle::~CRectangle() { nTotalNumber --; nTotalArea -= w * h; } void CRectangle::PrintTotal() { cout << nTotalNumber << "," << nTotalArea << endl; } int CRectangle::nTotalNumber = 0; int CRectangle::nTotalArea = 0; // 必须在定义类的文件中对静态成员变量进行一次说明或初始化。否则编译能通过,链接不能通过。 int main(){ CRectangle r1(3,3), r2(2,2); //cout << CRectangle::nTotalNumber; // Wrong , 私有 CRectangle::PrintTotal(); r1.PrintTotal(); return 0; }
输出结果: 2,13 2,13
成员对象: 一个类的成员变量是另一个类的对象,包含 成员对象 的类叫 封闭类 (Enclosing)
class CTyre { //轮胎类 private: int radius; //半径 int width; //宽度 public: CTyre(int r, int w):radius(r), width(w) { } };
class CEngine { //引擎类 }; class CCar { //汽车类 ? “封闭类” private: int price; //价格 CTyre tyre; CEngine engine; public: CCar(int p, int tr, int tw); }; CCar::CCar(int p, int tr, int w):price(p), tyre(tr, w){ }; int main(){ CCar car(20000,17,225); return 0; }
定义封闭类的构造函数时, 添加初始化列表:
类名::构造函数(参数表):成员变量1(参数表), 成员变量2(参数表), …
{
…
}
调用顺序
当封闭类对象生成时,
?S1: 执行所有成员对象 的构造函数
?S2: 执行 封闭类 的构造函数
成员对象的构造函数调用顺序
?和成员对象在类中的声明顺序一致
?与在成员初始化列表中出现的顺序无关
当封闭类的对象消亡时,
?S1: 先执行 封闭类 的析构函数
?S2: 执行 成员对象 的析构函数
析构函数顺序和构造函数的调用顺序相反
class CTyre { public: CTyre() { cout << "CTyre contructor" << endl; } ~CTyre() { cout << "CTyre destructor" << endl; } }; class CEngine { public: CEngine() { cout << "CEngine contructor" << endl; } ~CEngine() { cout << "CEngine destructor" << endl; } }; class CCar { private: CEngine engine; CTyre tyre; public: CCar( ) { cout << “CCar contructor” << endl; } ~CCar() { cout << "CCar destructor" << endl; } }; int main(){ CCar car; return 0; }
程序的输出结果是:
CEngine contructor
CTyre contructor
CCar contructor
CCar destructor
CTyre destructor
CEngine destructor
一个类的友元函数可以访问该类的私有成员
class CCar; //提前声明 CCar类, 以便后面CDriver类使用 class CDriver { public: void ModifyCar( CCar * pCar) ; //改装汽车 }; class CCar { private: int price; friend int MostExpensiveCar( CCar cars[], int total); //声明友元 friend void CDriver::ModifyCar(CCar * pCar); //声明友元 }; void CDriver::ModifyCar( CCar * pCar) { pCar->price += 1000; //汽车改装后价值增加 } int MostExpensiveCar( CCar cars[], int total) //求最贵汽车的价格 { int tmpMax = -1; for( int i = 0; i < total; ++i ) if( cars[i].price > tmpMax) tmpMax = cars[i].price; return tmpMax; } int main(){ return 0; }
将一个类的成员函数(包括构造, 析构函数)声明为另一个类的友元
class B { public: void function(); }; class A { friend void B::function(); };
A是B的友元类 则A的成员函数可以访问B的私有成员
class CCar { private: int price; friend class CDriver; //声明CDriver为友元类 }; class CDriver { public: CCar myCar; void ModifyCar() { //改装汽车 myCar.price += 1000; // CDriver是CCar的友元类?可以访问其私有成员 } }; int main() { return 0; }
注意:友元类之间的关系不能传递, 不能继承
其作用就是指向成员函数所作用 的对象。
非静态成员函数中可以直接使用this来代表指向该函数作用的对象的指针。
class Complex { public: double real, imag; void Print() { cout << real << "," << imag ; } Complex(double r,double i):real(r),imag(i){ } Complex AddOne() { this->real ++; //等价于 real ++; this->Print(); //等价于 Print return * this; } }; int main() { Complex c1(1,1),c2(0,0); c2 = c1.AddOne(); return 0; } //输出 2,1
静态成员函数中不能使用 this 指针!
因为静态成员函数并不具体作用与某个对象!
因此,静态成员函数的真实的参数的个数,就是程序中写出的参数个数!
标签:技术分享 const mod -- 常量 double mos 执行 文件
原文地址:http://www.cnblogs.com/xuanyuyt/p/6044367.html