类和对象(1)
有部分基础,只挑选容易遗漏以及比较重要的记录下。
一、访问类成员的两种方法
一种是对象,一种是指针,示例:
1 Person per;//对象用.方式 2 per.setpid(1); 3 int a=per.getpid(); 4 5 Person *per2 = new Person;//用指针的方式new出来,指针是箭头 6 per2->setpid(2); 7 int b=per2->getpid(); 8 9 delete per2;//用完之后要删掉,并且置空 10 per2 = NULL;
二、this指针的复习
成员函数有一个隐形的形参this,它指向该类对象的一个指针;可以在成员函数中显示的使用this指针;
使用时机:1,区分形参和成员数据;2,返回对象本身;3,返回对象的引用
示例:
1 class Person 2 { 3 private: 4 int m_pid; 5 string m_name; 6 int age; 7 8 public: 9 void setpid(int pid) { m_pid = pid; }; 10 int getpid() { return m_pid; }; 11 void setage(int age) ; 12 int getage() { return age; }; 13 Person *getinstance(); 14 Person &getref() ; 15 }; 16 17 void Person::setage(int age) 18 { 19 this->age = age; 20 } 21 22 Person* Person::getinstance() 23 { 24 return this; 25 } 26 27 Person& Person::getref() 28 { 29 return *this; 30 } 31 32 int main() 33 { 34 Person per; 35 per.setage(20); 36 cout << per.getage() << endl; 37 38 Person* per2 = per.getinstance(); 39 per2->setage(21); 40 cout << per2->getage() << endl; 41 42 system("pause"); 43 return 0; 44 }
三、类的作用域
1.静态成员函数可以直接使用域操作符::来访问,如:
1 class b 2 { 3 public: 4 int a; 5 int f(); 6 static int f1(); 7 }; 8 9 int main() 10 { 11 b::f1();//通过类名称来直接调用 12 }
2.形参表和函数体在类的作用域中,形参变量可以直接使用,函数可以相互直接调用。
但是静态的不能访问非静态的,而非静态的可以访问静态的。
四、构造函数
作用就是初始化成员变量,在创建对象时调用。
五、友元
允许一个类将对其非公有成员的访问授予指定的函数或类;只能出现在类的定义内部;可分为友元函数和友元类。
1 class A;//前置声明 2 3 class B 4 { 5 friend A; 6 friend void fx(B b); 7 public: 8 B():i(1), j(2) {};//构造函数初始化列表 9 private: 10 int i; 11 int j; 12 void f(); 13 }; 14 15 void B::f() 16 { 17 cout << i << "," << j << endl; 18 } 19 20 void fx(B b) 21 { 22 b.i = 100; 23 b.j = 200; 24 b.f(); 25 } 26 27 class A 28 { 29 public: 30 void f(B b); 31 }; 32 33 void A::f(B b)//B类里的i、j和f()都是私有的,但A是友元,所以可以访问B的私有变量 34 { 35 b.i = 100; 36 b.j = 200; 37 b.f(); 38 } 39 40 int main() 41 { 42 B b; 43 A a; 44 a.f(b); 45 fx(b); 46 47 system("pause"); 48 return 0; 49 }
六、复制构造函数
具有一个单独的该类型引用的形参;
当定义一个新对象,并用一个同类型对象初始化时,将会调用复制构造函数;
当该类型的对象传递给函数或从函数返回,将隐式使用复制构造函数。
1 class Person 2 { 3 public: 4 Person() {} 5 Person(Person& per){}//复制构造函数 6 }; 7 8 int main() 9 { 10 Person per; 11 Person per2(per);//调用复制构造函数 12 }
使用时机:
1.根据另一个同类型对象显式或隐式初始化另一个对象;
2.复制一个对象,将其作为一个实参传给一个函数;
3.从一个函数返回时复制一个对象;
4.初始化顺序容器中的元素;
5.根据元素初始化列表初始化数组元素。
1 class A 2 { 3 private: 4 int i; 5 public: 6 //构造函数 7 A(); 8 A(int i) :i(i) { cout << "调用默认构造函数" << endl; } 9 //析构函数 10 ~A(); 11 //复制构造函数 12 A(A& a) { this->i = a.i; cout << "调用复制构造函数" << endl;} 13 //打印函数 14 void print() { cout << i << endl; } 15 //传递对象 16 void print2(A a) { a.print(); } 17 //返回对象 18 A getRef() { return *this; } 19 }; 20 21 A::A()//不写会报错 22 { 23 cout << "调用默认构造函数" << endl; 24 } 25 26 A::~A() 27 { 28 cout << "调用析构函数" << endl; 29 } 30 31 int main() 32 { 33 A a(100); 34 a.print(); 35 36 A a1(a); 37 a1.print(); 38 39 //传参 40 a.print2(a); 41 42 //返回一个引用,不能直接A a2=...,否则会报错 43 A a2; 44 a2=a.getRef(); 45 a2.print(); 46 47 48 system("pause"); 49 return 0; 50 }
七、其他
初始化方式有两种,直接初始化(使用括号,int i(100)),复制初始化使用=号;
类类型对象的直接初始化直接调用与实参相匹配的构造函数,复制初始化总是调用复制构造函数;
复制初始化,会首先使用指定构造构造函数创建一个临时对象,然后复制构造函数将那个临时对象复制到正在创建的对象;
若没有显式定义复制构造函数,系统会提供默认复制构造函数;