打赏

5.4-day04-C++拷贝构造函数/静态成员

一、拷贝构造函数和拷贝赋值运算符
1.拷贝构造:用一个已有的对象,构造和它同类型的副本对象——克隆。
2.形如
class X {
  X (const X& that) { ... }
};
的构造函数成为拷贝构造函数。如果一个类没有定义拷贝构造函数,系统会提供一个缺省拷贝构造函数。缺省拷贝构造函数对于基本类型的成员变量,按字节复制,对于类类型的成员变量,调用相应类型的拷贝构造函数。
3.在某些情况就下,缺省拷贝构造函数只能实现浅拷贝,如果需要获得深拷贝的复制效果,就需要自己定义拷贝构造函数。
4.形如
class X {
  X& operator= (const X& that) {
    ...
  }
};
的成员函数称为拷贝赋值运算符函数。如果一个类没有定义拷贝赋值运算符函数,系统会提供一个缺省拷贝赋值运算符函数。缺省拷贝赋值运算符函数对于基本类型的成员变量,按字节复制,对于类类型的成员变量,调用相应类型的拷贝赋值运算符函数。
5.在某些情况就下,缺省拷贝赋值运算符函数只能实现浅拷贝,如果需要获得深拷贝的复制效果,就需要自己定义拷贝赋值运算符函数。
练习:实现一个简化版的字符串类String支持:
1.用字符指针形式的字符串构造
2.拷贝构造和拷贝赋值
3.获取字符指针形式字符串的成员函数,类似string::c_str
说明:不得使用std::string!
二、静态成员
1.静态成员变量和静态成员函数是属于类的而非属于对象。
2.静态成员变量,为多个对象所共享,只有一份实例,可以通过对象访问也可以通过类访问,必须在类的外部定义并初始化。静态成员变量本质上与全局变量并没有区别,只是多了类作用域的约束,和访控属性的限制。
class Account {
private:
  string m_name;
  double m_balance;
  static double m_rate;
};
3.静态成员函数,没有this指针,无法访问非静态成员。
4.单例模式
三、成员指针
Student s;
string* p = &s.m_name; // 不是
Student s2;
(一)成员变量指针
1.定义
成员变量类型 类名::*指针变量名;
string Student::*pname;
int Student::*page;
2.初始化/赋值
指针变量名 = &类名::成员变量名
pname = &Student::m_name;
page = &Student::m_age;
3.解引用
对象.*指针变量名
对象指针->*指针变量名
Student s, *p = &s;
s.*pname = "张飞";
cout << p->*page << endl;
(二)成员函数指针
1.定义
成员函数返回类型 (类名::*指针变量名) (参数表)
void (Student::*plearn) (const string&) const;
2.初始化/赋值
指针变量名 = &类名::成员函数名;
plearn = &Stduent::learn;
3.解引用
(对象.*指针变量名) (实参表);
(对象指针->*指针变量名) (实参表);
(s.*plearn) ("C++");
(p->*plearn) ("UNIX");
第三课  操作符重载
复数:3+4i
Complex
c1 - (c2 + c3)
c1.sub (c2.add (c3)) 
一、操作符标记和操作符函数
1.双目操作符:L#R
成员函数形式:L.operator# (R)
左调右参
全局函数形式:::operator# (L, R)
左一右二
2.单目操作符:#O/O#
成员函数形式:O.operator# ()
全局函数形式:::operator# (O)
3.三目操作符:不考虑
二、双目操作符
1.+/-/*//
操作数在计算前后不变。
表达式的值是右值。
 

complex.cpp
  1. #include<iostream>
  2. usingnamespace std;
  3. classComplex{
  4. public:
  5. Complex(int r =0,int i =0):
  6. m_r (r), m_i (i){}
  7. void print (void)const{
  8. cout << m_r <<'+'<< m_i <<'i'<< endl;
  9. }
  10. // 第一个const:返回右值
  11. // 第二个const:支持常量型右操作数
  12. // 第三个const:支持常量型左操作数
  13. constComplexoperator+(
  14. constComplex& r)const{
  15. returnComplex(m_r + r.m_r, m_i + r.m_i);
  16. }
  17. private:0
  18. int m_r;
  19. int m_i;
  20. friendconstComplexoperator-(constComplex&,
  21. constComplex&);
  22. };
  23. constComplexoperator-(constComplex& l,
  24. constComplex& r){
  25. returnComplex(l.m_r - r.m_r, l.m_i - r.m_i);
  26. }
  27. int main (void){
  28. constComplex c1 (1,2);
  29. c1.print ();
  30. constComplex c2 (3,4);
  31. Complex c3 = c1 + c2;// c3 = c1.operator+ (c2)
  32. c3.print ();// 4+6i
  33. // (c1 + c2) = c3;
  34. c3 = c2 - c1;// c3 = ::operator- (c2, c1)
  35. c3.print ();// 2+2i
  36. return0;
  37. }
 
hungry.cpp
  1. #include<iostream>
  2. usingnamespace std;
  3. // 饿汉方式
  4. classSingleton{
  5. public:
  6. staticSingleton& getInst (void){
  7. return s_inst;
  8. }
  9. private:
  10. Singleton(void){}
  11. Singleton(constSingleton&);
  12. staticSingleton s_inst;
  13. };
  14. SingletonSingleton::s_inst;
  15. int main (void){
  16. Singleton& s1 =Singleton::getInst ();
  17. Singleton& s2 =Singleton::getInst ();
  18. Singleton& s3 =Singleton::getInst ();
  19. cout <<&s1 <<' '<<&s2 <<' '<<&s3 << endl;
  20. return0;
  21. }
 

integer.cpp
  1. #include<iostream>
  2. usingnamespace std;
  3. classInteger{
  4. public:
  5. Integer(int data =0): m_data (data){}
  6. void print (void)const{
  7. cout << m_data << endl;
  8. }
  9. /*
  10. Integer (const Integer& that) :
  11. m_data (that.m_data) {
  12. cout << "拷贝构造" << endl;
  13. }
  14. */
  15. private:
  16. int m_data;
  17. };
  18. void foo (Integer i){
  19. i.print ();
  20. }
  21. Integer bar (void){
  22. Integer i;
  23. return i;
  24. }
  25. int main (void){
  26. Integer i1 (10);
  27. i1.print ();
  28. Integer i2 (i1);// 拷贝构造
  29. i2.print ();
  30. Integer i3 = i1;// 拷贝构造
  31. i3.print ();
  32. // Integer i4 (10, 20);
  33. cout <<"调用foo()函数"<< endl;
  34. foo (i1);
  35. cout <<"调用bar()函数"<< endl;
  36. Integer i4 (bar ());
  37. return0;
  38. }
 

integer2.cpp
  1. #include<iostream>
  2. usingnamespace std;
  3. classInteger{
  4. public:
  5. Integer(int data): m_data (newint(data)){}
  6. ~Integer(void){
  7. if(m_data){
  8. delete m_data;
  9. m_data = NULL;
  10. }
  11. }
  12. void print (void)const{
  13. cout <<*m_data << endl;
  14. }
  15.  
  16. Integer(constInteger& that):
  17. m_data (newint(*that.m_data)){}
  18. voidset(int data){
  19. *m_data = data;
  20. }
  21. Integer&operator=(constInteger& that){
  22. // 防止自赋值
  23. if(&that !=this){
  24. // 释放旧资源
  25. delete m_data;
  26. // 分配新资源
  27. m_data =newint(*that.m_data);
  28. // 拷贝新数据
  29. }
  30. // 返回自引用
  31. return*this;
  32. }
  33. private:
  34. int* m_data;
  35. };
  36. int main (void){
  37. Integer i1 (10);
  38. i1.print ();
  39. Integer i2 (i1);
  40. i2.print ();
  41. i2.set(20);
  42. i2.print ();
  43. i1.print ();
  44. Integer i3 (30);
  45. i3.print ();// 30
  46. i3 = i1;// 拷贝赋值
  47. // i3.operator= (i1);
  48. i3.print ();// 10
  49. i3.set(40);
  50. i3.print ();// 40
  51. i1.print ();// 10
  52. /*
  53. int a = 10, b = 20, c = 30;
  54. (a = b) = c;
  55. cout << a << endl;
  56. */
  57. (i3 = i1)= i2;
  58. // i3.operator=(i1).operator=(i2);
  59. i3.print ();
  60. i3 = i3;
  61. i3.print ();
  62. return0;
  63. }
 

lazy.cpp
  1. #include<iostream>
  2. usingnamespace std;
  3. // 懒汉方式
  4. classSingleton{
  5. public:
  6. staticSingleton& getInst (void){
  7. if(! m_inst)
  8. m_inst =newSingleton;
  9. ++m_cn;
  10. return*m_inst;
  11. }
  12. void releaseInst (void){
  13. if(m_cn &&--m_cn ==0)
  14. deletethis;
  15. }
  16. private:
  17. Singleton(void){
  18. cout <<"构造:"<<this<< endl;
  19. }
  20. Singleton(constSingleton&);
  21. ~Singleton(void){
  22. cout <<"析构:"<<this<< endl;
  23. m_inst = NULL;
  24. }
  25. staticSingleton* m_inst;
  26. staticunsignedint m_cn;
  27. };
  28. Singleton*Singleton::m_inst = NULL;
  29. unsignedintSingleton::m_cn =0;
  30. int main (void){
  31. Singleton& s1 =Singleton::getInst ();
  32. Singleton& s2 =Singleton::getInst ();
  33. Singleton& s3 =Singleton::getInst ();
  34. cout <<&s1 <<' '<<&s2 <<' '<<&s3 << endl;
  35. s3.releaseInst ();
  36. s2.releaseInst ();
  37. s1.releaseInst ();
  38. return0;
  39. }

memptr.cpp
  1. #include<iostream>
  2. #include<cstring>
  3. usingnamespace std;
  4. classStudent{
  5. public:
  6. Student(const string& name,int age):
  7. m_name (name), m_age (age){}
  8. double m_weight;
  9. string m_name;
  10. int m_age;
  11. void learn (const string& lesson)const{
  12. cout <<"我在学"<< lesson << endl;
  13. }
  14. staticvoid hello (void){
  15. cout <<"你好!"<< endl;
  16. }
  17. };
  18. int main (void){
  19. string Student::*pname =&Student::m_name;
  20. void* pv;
  21. memcpy (&pv,&pname,4);
  22. cout << pv << endl;
  23. intStudent::*page =&Student::m_age;
  24. memcpy (&pv,&page,4);
  25. cout << pv << endl;
  26. Student s ("张飞",25),*p =&s;
  27. cout << s.*pname << endl;
  28. cout << p->*page << endl;
  29. Student s2 ("赵云",22);
  30. cout << s2.*pname << endl;
  31. void(Student::*plearn)(const string&)const=
  32. &Student::learn;
  33. (s.*plearn)("C++");
  34. (p->*plearn)("UNIX");
  35. void(*phello)(void)=Student::hello;
  36. phello ();
  37. return0;
  38. }
 

private.cpp
  1. #include<iostream>
  2. usingnamespace std;
  3. classNocopy{
  4. public:
  5. Nocopy(void){}
  6. private:
  7. Nocopy(constNocopy&);
  8. Nocopy&operator=(constNocopy&);
  9. };
  10. void foo (ostream os){
  11. os <<"Hello, World !"<< endl;
  12. }
  13. int main (void){
  14. Nocopy n1;
  15. Nocopy n2 = n1;
  16. Nocopy n3;
  17. n3 = n1;
  18. foo (cout);
  19. return0;
  20. }
 

 
static.cpp
  1. #include<iostream>
  2. usingnamespace std;
  3. class A {
  4. public:
  5. staticint m_i;
  6. staticvoid foo (void){
  7. cout <<"foo:"<< m_i << endl;
  8. // m_d = 3.14;
  9. // bar ();
  10. }cd
  11. double m_d;
  12. void bar (void){
  13. m_i =1000;
  14. foo ();
  15. }
  16. };
  17. int A::m_i =1;
  18. int main (void){
  19. A::m_i =10;
  20. A a1, a2;
  21. cout <<++a1.m_i << endl;
  22. cout << a2.m_i << endl;
  23. A::foo ();
  24. a1.foo ();
  25. a1.bar ();
  26. return0;
  27. }
 

string.cpp
  1. #include<iostream>
  2. #include<cstring>
  3. ::usingnamespace std;
  4. classString{
  5. public:
  6. String(constchar* str = NULL){
  7. m_str =newchar[strlen(str?str:"")+1];
  8. strcpy (m_str, str ? str :"");
  9. }
  10. ~String(void){
  11. if(m_str){
  12. delete[] m_str;
  13. m_str = NULL;
  14. }
  15. }
  16. String(constString& that):
  17. m_str (strcpy (
  18. newchar[strlen(that.m_str)+1],
  19. that.m_str)){}
  20. /* 菜鸟
  21. void operator= (const String& that) {
  22. m_str = new char[strlen(that.m_str)+1];
  23. strcpy (m_str, that.m_str);
  24. }*/
  25. String&operator=(constString& that){
  26. if(&that !=this){
  27. /* 小鸟
  28. delete[] m_str;
  29. m_str = new char[strlen(that.m_str)+1];
  30. strcpy (m_str, that.m_str);
  31. */
  32. /* 大鸟
  33. char* str =
  34. new char[strlen(that.m_str)+1];
  35. delete[] m_str;
  36. m_str = strcpy (str, that.m_str);
  37. */
  38. // 老鸟
  39. String temp (that);
  40. swap (m_str, temp.m_str);
  41. }
  42. return*this;
  43. }
  44. constchar* c_str (void)const{
  45. return m_str;
  46. }
  47. private:
  48. char* m_str;
  49. };
  50. int main (void){
  51. String s1 ("Hello, World !");
  52. cout << s1.c_str ()<< endl;
  53. String s2 = s1;
  54. cout << s2.c_str ()<< endl;
  55. String s3 ("Hello, Linux !");
  56. try{
  57. s1 = s3;
  58. }
  59. catch(exception& ex){
  60. cout << ex.what ()<< endl;
  61. }
  62. cout << s1.c_str ()<< endl;
  63. return0;
  64. }
 
 拷贝构造:
       如果一个类没有定义拷贝构造函数,系统会提供一个缺省拷贝构造函数。缺省拷贝构造函数对于基本类型的成员变量,按字节复制,对于类类型的成员变量,调用相应类型的拷贝构造函数。
 
 

<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">





posted on 2018-11-29 22:59  XuCodeX  阅读(223)  评论(0编辑  收藏  举报

导航