zoukankan      html  css  js  c++  java
  • 一.类成员函数的定义方法

    1.在类声明中声明,类声明外定义

     1 #include<iostream>
     2 using namespace std;
     3 
     4 class Person
     5 {
     6 public:
     7     void setAge(unsigned n);
     8     unsigned getAge() const;
     9 private:
    10     unsigned age;
    11 };
    12 
    13 void Person::setAge(unsigned n)
    14 {
    15     age = n;
    16 }
    17 
    18 unsigned Person::getAge() const
    19 {
    20     return age;
    21 }
    22 
    23 int main()
    24 {
    25     return 0;
    26 }

    2.在类声明中声明和定义

     1 #include<iostream>
     2 using namespace std;
     3 
     4 class Person
     5 {
     6 public:
     7     void setAge(unsigned n)
     8     {
     9         age = n;
    10     }
    11 
    12     unsigned getAge() const
    13     {
    14         return age;
    15     }
    16 private:
    17     unsigned age;
    18 };
    19 
    20 int main()
    21 {
    22     return 0;
    23 }

    二.类声明通常放到.h文件中,不要将成员函数的定义放到.h中

    三.一般来说应该采用引用的方式进行对象的传递和返回,而不要采用传值。传递一个指向对象的指针和引用方式效果相同,但引用语法简练。

    四.const用法

    const成员函数仅能调用其它const成员函数,非const成员函数可能会间接地改变对象状态

    1.重载,2个成员函数(函数名,参数列表)一致,但一个有const一个无

    不算重名,算重载

    常对象调用常函数,非常对象调用非常函数

     1 #include<iostream>
     2 using namespace std;
     3 
     4 class A
     5 {
     6 public:
     7     A()
     8     {
     9         x = 5;
    10     }
    11     int getValue()
    12     {
    13         return x;
    14     }
    15 
    16     int getValue() const
    17     {
    18         return 2 * x;
    19     }
    20 private:
    21     unsigned x;
    22 };
    23 
    24 int main()
    25 {
    26     A a1;
    27     const A a2;
    28     cout << a1.getValue() << endl; // 5
    29     cout << a2.getValue() << endl; // 10
    30     return 0;
    31 }

    2.三种const

     1 #include<iostream>
     2 using namespace std;
     3 
     4 class C
     5 {
     6 public:
     7     void set(const int n)//set不会改变n
     8     {
     9         x = n;
    10     }
    11 
    12     const int& get() const//第一个const:get会返回一个const型引用,谁也不能通过这个引用修改x,不能修改返回值
    13     {                     //第二个const:get不会改变C中的数据成员
    14         return x;
    15     }
    16 private:
    17     int x
    18 };
    19 
    20 int main()
    21 {
    22     return 0;
    23 }

    若函数采用const返回,则返回值只赋给一个const类型局部变量;

    const返回值是一个类的指针或者引用的话,则不能用该指针或者引用调用该类的non-const成员函数,因为这些函数可能会改变该类数据成员;

    常量对象不能执行非常量成员函数。

     1 #include<iostream>
     2 using namespace std;
     3 
     4 class C
     5 {
     6 public:
     7     int &f1()
     8     {
     9         mszt = 5;
    10         return mszt; // 可修改mstz,可修改返回值
    11     }
    12 
    13     int &f2() const
    14     {
    15         return a; // error,无法将const int转换为int&,去掉&
    16     }
    17 
    18     const int& f3()
    19     {
    20         a = 5;
    21         return a; //可修改a,不可修改返回值
    22     }
    23 
    24     void PrintMszt()
    25     {
    26         cout << mszt << endl;
    27     }
    28 
    29     void PrintA()
    30     {
    31         cout << a << endl;
    32     }
    33 private:
    34     int mszt, a;
    35 };
    36 
    37 int main()
    38 {
    39     C c;
    40     int &s = c.f3(); // error,s不是const
    41     const int& s1 = c.f3(); //ok
    42     cout << s1 << endl;
    43     s1 = 20;//error
    44     return 0;
    45 }

    3.对const成员不能直接赋值

     1 #include <iostream>
     2 #include <string>
     3 using namespace std;
     4 
     5 class C
     6 {
     7 public:
     8     C():c(0)//要用初始化列表
     9     {
    10         x = -1;
    11     }
    12 
    13 private:
    14     const int c;
    15     int x;
    16 };
    17 
    18 int main()
    19 {
    20     return 0;
    21 }

    五.构造函数

    1.构造函数无返回类型,与类同名;

    2.创建一个对象时,构造函数会被编译器自动调用;

    3.希望只使用带参构造函数时,提供公有带参构造函数,而不提供默认构造函数,或者提供私有的默认构造函数

     1 #include<iostream>
     2 using namespace std;
     3 
     4 class C
     5 {
     6 public:
     7     C(int a) {}
     8 private:
     9     C() {}
    10 };
    11 
    12 int main()
    13 {
    14     C c;//error
    15     C c(1);//OK
    16     return 0;
    17 }

    六.拷贝构造

    Person(Person&); Person(const Person&);

    拷贝构造函数可以有多于一个的参数,但第一个以后的所有参数都必须有默认值

    Person(const Person& p, bool married = false);

    若一个类包含指向动态存储空间指针类型的数据成员,应为这个类设计拷构。否则:

     1 #include<iostream>
     2 using namespace std;
     3 
     4 class P
     5 {
     6 public:
     7     P();
     8     P(const string[], int);
     9     void set(const string[], int);
    10 private:
    11     int size;
    12     string *p;
    13 };
    14 
    15 int main()
    16 {
    17     string list[10];
    18     P p1(list, 3);
    19     P p2(p1);//默认拷构
    20     return 0;
    21 }

    p1.p和p2.p指向同一块存储空间,潜在p1的操作会改变p2,且调用析构时会对同一值析构两次。

     1 #include<iostream>
     2 using namespace std;
     3 
     4 class C
     5 {
     6 public:
     7     C()
     8     {
     9         cout << "Default" << endl;
    10         num = 0;
    11     }
    12 
    13     C(const C &c)
    14     {
    15         cout << "Copy" << endl;
    16         //num = c.num;若有,若无
    17     }
    18 
    19     void set(int n)
    20     {
    21         num = n;
    22     }
    23 
    24     int get() const
    25     {
    26         return num;
    27     }
    28 private:
    29     int num;
    30 };
    31 
    32 void f(C c4)//copy
    33 {
    34     cout << "enter f(c)" << '	';
    35     c4.set(-999);
    36     cout << "c4:" << c4.get() << '	' << "leaving f(c)" << endl;
    37 }
    38 
    39 C g()
    40 {
    41     cout << "enter g()" << endl;
    42     C c3;//default
    43     cout << "c3:" << c3.get() << '
    ';
    44     c3.set(123);
    45     cout << "c3:" << c3.get() << '	' << "leaving g()" << endl;
    46     return c3;//copy
    47 }
    48 
    49 int main()
    50 {
    51     C c1, c2;//default
    52     cout << "c1:" << c1.get() << '	';
    53     cout << "c2:" << c2.get() << endl;
    54     f(c1);
    55     cout << "c1:" << c1.get() << endl;
    56     c2 = g();
    57     cout << "c2:" << c2.get() << endl;//若有123,若无乱码
    58     return 0;
    59 }

    用一个已存在的对象去构造一个不存在的对象(构造之前不存在)就是拷贝构造。用一个已存在的对象去覆盖另一个已存在的对象,就是赋值运算。

    若对象很大,进行对象间的拷贝的话,非常费空间和时间,改进:

          把拷贝构造设计成私有成员;

          把void f(C c)=> void f(C &c),C g()=>C &g()

    七.转型构造函数(单参数构造函数)

     1 #include<iostream>
     2 using namespace std;
     3 
     4 class Complex
     5 {
     6 public:
     7     Complex(int i)
     8     {
     9         cout << "Int Constructor" << endl;
    10         real = i, imag = 0;
    11     }
    12 
    13     Complex(double r, double i)
    14     {
    15         cout << "Double Constructor" << endl;
    16         real = r, imag = i;
    17     }
    18 
    19     Complex(Complex &c)
    20     {
    21         cout << "Copy Constructor" << endl;
    22         real = c.real;
    23         imag = c.imag;
    24     }
    25 
    26     int real, imag;
    27 };
    28 
    29 int main()
    30 {
    31     Complex c1(7, 8);//Double Constructor
    32     Complex c2 = 12;//Int Constructor
    33     c1 = 9;//Int Constructor, 9隐式类型转换
    34     cout << c1.real << " " << c2.imag << endl;//9 0
    35     Complex c3 = c1;//Copy Constructor
    36     return 0;
    37 }
     1 #include <iostream>
     2 #include <string>
     3 using namespace std;
     4 
     5 class Person
     6 {
     7 public:
     8     Person()
     9     {
    10         name = "Unknown";
    11     }
    12 
    13     Person(const string &n)//转型构造
    14     {
    15         cout << "转型" << endl;
    16         name = n;
    17     }
    18 
    19     Person(const char *n)//转型构造
    20     {
    21         cout << "转型" << endl;
    22         name = n;
    23     }
    24 
    25     Person(Person &p)//转型构造
    26     {
    27         cout << "Copy" << endl;
    28         name = p.name;
    29     }
    30 
    31     string name;
    32 };
    33 
    34 void f(Person p)
    35 {
    36     cout << 1 << endl;
    37 }
    38 
    39 int main()
    40 {
    41     Person s1("Dave");
    42     Person s2("Ben");
    43     string str = "Peter";
    44     f(str);//显示“转型”,不显示“转型”,在构造时,调用了转型构造函数
    45     s1 = str;//str转型为Person类型,显示“转型”
    46     s1 = s2;//什么都不显示,不存在Copy和转型
    47     return 0;
    48 }
     1 #include <iostream>
     2 #include <string>
     3 using namespace std;
     4 
     5 class Person
     6 {
     7 public:
     8     Person()
     9     {
    10         name = "Unknown";
    11     }
    12 
    13     explicit Person(const string &n)//在转型构造函数前加上explicit,关闭隐式类型转换
    14     {
    15         name = n;
    16     }
    17 private:
    18     string name;
    19 };
    20 
    21 int main()
    22 {
    23     Person p("Dave");
    24     string b = "bar";
    25     p = b;//error
    26     return 0;
    27 }

     

    八.析构函数

    析构函数没有参数和返回值,一个类最多一个析构函数

    定义类时没写析构函数,则编译器生成缺省析构函数,不涉及释放用户申请的内存释放等清理工作。

     1 #include<iostream>
     2 using namespace std;
     3 
     4 class C
     5 {
     6 public:
     7     C()
     8     {
     9         cout << "Construct" << endl;
    10     }
    11     ~C()
    12     {
    13         cout << "Destructor" << endl;
    14     }
    15 };
    16 
    17 int main()
    18 {
    19     C c1[2], *c2 = new C[3];
    20     return 0;
    21 }
    22 /*
    23 Construct
    24 Construct
    25 Construct
    26 Construct
    27 Construct
    28 Destructor
    29 Destructor
    30 */
     1 #include<iostream>
     2 using namespace std;
     3 
     4 class C
     5 {
     6 public:
     7     C()
     8     {
     9         cout << "Construct" << endl;
    10     }
    11     ~C()
    12     {
    13         cout << "Destructor" << endl;
    14     }
    15 };
    16 
    17 int main()
    18 {
    19     C *c2 = new C[3];
    20     delete[] c2;
    21     return 0;
    22 }
    23 /*
    24 Construct
    25 Construct
    26 Construct
    27 Destructor
    28 Destructor
    29 Destructor
    30 */
  • 相关阅读:
    Android相对布局中控件的常用属性【转】
    Android:仿微信设置菜单
    Android:scrollview与listview共存
    感想12.26
    (C#)GDI+绘制垂直文字
    10.14 近期小结
    学习C++的忠告
    C# TCP学习笔记
    C#读书笔记(4)—重学数组
    近期学习计划 12.23
  • 原文地址:https://www.cnblogs.com/wanderingzj/p/5294784.html
Copyright © 2011-2022 走看看