• C++中对象、引用、指针


    C++中对象和java中对象不一样,java中对象都是引用类型。例如

     1 public static void main(String[] args) {
     2         Student stu = new Student(); // 创建一个Student对象
     3         stu.setName("zhangsan"); // 设置名字为‘张三’
     4         stu.setAge(18); // 设置年龄为18
     5 
     6         // 打印姓名和年龄
     7         System.out.println("name = " + stu.getName());
     8         System.out.println("age = " + stu.getAge());
     9 
    10         handleStudent(stu); // 调用修改学生的姓名年龄的方法
    11 
    12         System.out.println("调用处理方法之后:");
    13         // 打印姓名和年龄,发现数据已经发生变化
    14         System.out.println("name = " + stu.getName()); // 打印修改之后的名字
    15         System.out.println("age = " + stu.getAge()); // 打印修改之后的年龄
    16     }
    17 
    18     /**
    19      * 对学生的姓名年龄做修改
    20      * 
    21      * @param stu
    22      */
    23     public static void handleStudent(Student stu) {
    24         stu.setName("lisi");
    25         stu.setAge(20);
    26     }
    27 
    28     /**
    29      * 学生类
    30      * 
    31      * @author Baoyz
    32      * 
    33      */
    34     static class Student {
    35         private String name;
    36         private int age;
    37 
    38         public String getName() {
    39             return name;
    40         }
    41 
    42         public void setName(String name) {
    43             this.name = name;
    44         }
    45 
    46         public int getAge() {
    47             return age;
    48         }
    49 
    50         public void setAge(int age) {
    51             this.age = age;
    52         }
    53 
    54     }

    输出结果:

      name = zhangsan
      age = 18
      调用处理方法之后:
      name = lisi
      age = 20

     一个方法接收一个对象,调用方法传入的对象是这个对象的引用,也就是方法中操作的对象和传入的是同一个地址的同一个对象。在方法中对改对象作出的操作都会直接影响传入的对象。

     而在C++中并不是这样,例如

     1 // 学生类
     2 class Student
     3 {
     4 private:
     5     string name;
     6     int age;
     7 public:
     8     void setName(string);
     9     void setAge(int);
    10     string getName();
    11     int getAge();
    12 };
    13 
    14 void handleStudent(Student);
    15 
    16 int main()
    17 {
    18     Student stu;    // 创建学生对象
    19     stu.setAge(18);    // 设置年龄
    20     stu.setName("zhangsan");    // 设置姓名
    21 
    22     // 打印姓名和年龄
    23     cout << "name = " << stu.getName() << endl;
    24     cout << "age = " << stu.getAge() << endl;
    25 
    26     handleStudent(stu);    // 调用修改学生的姓名年龄的方法
    27 
    28     cout << "调用处理方法之后:" << endl;
    29     // 打印姓名和年龄,发现数据并没有变化
    30     cout << "name = " << stu.getName() << endl;
    31     cout << "age = " << stu.getAge() << endl;
    32 
    33 }
    34 
    35 // 对学生的姓名年龄做修改
    36 void handleStudent(Student stu)
    37 {
    38     stu.setAge(20);
    39     stu.setName("lisi");
    40 }
    41 
    42 void Student::setName(string name)
    43 {
    44     this->name = name;
    45 }
    46 
    47 void Student::setAge(int age)
    48 {
    49     this->age = age;
    50 }
    51 
    52 string Student::getName()
    53 {
    54     return this->name;
    55 }
    56 
    57 int Student::getAge()
    58 {
    59     return this->age;
    60 }

    运行结果:

      name = zhangsan
      age = 18
      调用处理方法之后:
      name = zhangsan
      age = 18

    C++中,把一个对象传入一个方法(函数),相当于把这个对象原封不动的复制了一份给形参,操作的并不是同一个对象。

    在C++中还有两个容易混乱的概念 引用和指针。

    引用类型,声明时候必须要初始化,相当于给变量起了一个别名。例如

    int i = 10;    // 创建一个变量i并赋值10
        int &j = i;    // 创建一个引用类型变量j,并初始化,相当于给i起了一个别名叫做j,i和j是同一个数据的两个名字
    
        cout << "i = " << i << endl;    // 输出10
        cout << "j = " << j << endl;    // 输出10
    
        i = 20;    // 更改i的值为20
    
        cout << "i = " << i << endl;    // 输出20
        cout << "j = " << j << endl;    // 输出20
    
        j = 50;    // 更改j的值为50
    
        cout << "i = " << i << endl;    // 输出50
        cout << "j = " << j << endl;    // 输出50

    引用类型和被引用的变量的数据是同一个,只不过这个数据有两个名字。
    既然引用类型可以起别名,最终的数据还是同一个,我们可以把方法的形参声明为引用类型,还是上面学生的例子。看看什么效果

     1 // 学生类
     2 class Student
     3 {
     4 private:
     5     string name;
     6     int age;
     7 public:
     8     void setName(string);
     9     void setAge(int);
    10     string getName();
    11     int getAge();
    12 };
    13 
    14 void handleStudent(Student &);    // 更改为引用类型
    15 
    16 int main()
    17 {
    18     Student stu;    // 创建学生对象
    19     stu.setAge(18);    // 设置年龄
    20     stu.setName("zhangsan");    // 设置姓名
    21 
    22     // 打印姓名和年龄
    23     cout << "name = " << stu.getName() << endl;
    24     cout << "age = " << stu.getAge() << endl;
    25 
    26     handleStudent(stu);    // 调用修改学生的姓名年龄的方法,参数是引用类型
    27 
    28     cout << "调用处理方法之后:" << endl;
    29     // 打印姓名和年龄,发现数据变化,因为处理方法中形参是引用类型,操作的是同一个数据
    30     cout << "name = " << stu.getName() << endl;
    31     cout << "age = " << stu.getAge() << endl;
    32 }
    33 
    34 // 对学生的姓名年龄做修改,形参是引用类型
    35 void handleStudent(Student & stu)
    36 {
    37     stu.setAge(20);
    38     stu.setName("lisi");
    39 }
    40 
    41 void Student::setName(string name)
    42 {
    43     this->name = name;
    44 }
    45 
    46 void Student::setAge(int age)
    47 {
    48     this->age = age;
    49 }
    50 
    51 string Student::getName()
    52 {
    53     return this->name;
    54 }
    55 
    56 int Student::getAge()
    57 {
    58     return this->age;
    59 }

    运行结果:

      name = zhangsan
      age = 18
      调用处理方法之后:
      name = lisi
      age = 20

    发现调用方法之后,原来对象的数据也发现了变化,说明方法中操作的对象和传入的对象是同一个。

    引用类型,引用类型其实和int,char是一样的,int存放的是整数,char存放的是字符,引用类型存放的是地址,只不过因为一个符号“*”搞乱了很多人。

    看一个例子

        int i = 10;    // 定义一个int变量i,并赋值,由于int类型存放的是整数,所以可以赋值一个整数10
        int* j = &i;    // 定义一个int指针变量j,由于指针类型存放的是地址,所以赋值一个地址&i,‘&’是取地址符号,&i就是i的地址
    
        // 我们要把int* j = &i; 中的"int*"看做一个整体,是一种类型
    
        cout << "整型变量i = " << i << endl;    // 输出 “整型变量i = 10”
        cout << "整型指针变量j = " << j << endl;    // 输出 “整型指针变量j = 0035FA5C”

    “int*” 是一种类型,“int”是一种类型,例子中int i 的值是10,int* j 的值是0035FA5C,这是个内存地址。

    然后介绍一个操作符“*”,这个“*”和int*中的是不一样的,不要混淆,int*是一个类型,是一东西,不是两个东西。单独一个“*”是一个操作符。

    我把“*”叫做 取值符,与“&”取址符对应。“*”的后面是地址,意思是取地址上面的值;“&”后面是变量,意思是取变量数据的地址。

        int i = 10;    // 定义一个int变量并赋值10
        int* j;    // 定义一个int指针类型
        j = &i;    // 使用取址符,获取int i的地址,将地址赋值给int* j
        // 通过&i得到i的地址,把这个地址赋值给j,j里面存放了一个地址
        int k = *j;    // 使用取值符,获取j中地址上面的值,由于j是int指针类型,存放的地址上面的数据必须是是int类型,将获取的数据赋值给int k
        
        cout << "从指针j存放的地址上面取到的值是:k = " << k << endl;    // 打印k为10

    一个指针变量,只是单纯存放了一个地址(就是一串数字编号),并无特别之处。只是我们可以通过“*”取值符获取改指针变量存放地址上面的数据。有了这个概念,我们在看看上面学生的例子。

     1 #include <iostream>
     2 #include <string>
     3 
     4 using namespace std;
     5 
     6 // 学生类
     7 class Student
     8 {
     9 private:
    10     string name;
    11     int age;
    12 public:
    13     void setName(string);
    14     void setAge(int);
    15     string getName();
    16     int getAge();
    17 };
    18 
    19 void handleStudent(Student *);    // 更改为指针类型
    20 
    21 int main()
    22 {
    23     Student stu;    // 创建学生对象
    24     stu.setAge(18);    // 设置年龄
    25     stu.setName("zhangsan");    // 设置姓名
    26 
    27     // 打印姓名和年龄
    28     cout << "name = " << stu.getName() << endl;
    29     cout << "age = " << stu.getAge() << endl;
    30 
    31     // handleStudent(stu);    // 这样写是错的,参数是指针类型存放的是地址,要传入一个地址不是对象
    32     handleStudent(&stu);    // 通过“&”取址符获取对象的地址传入该方法
    33 
    34     cout << "调用处理方法之后:" << endl;
    35     // 打印姓名和年龄,发现数据变化,因为处理方法中形参是引用类型,通过“*”获取该地址上面的数据(对象)进行操作,与原对象是同一个
    36     cout << "name = " << stu.getName() << endl;
    37     cout << "age = " << stu.getAge() << endl;
    38 
    39 }
    40 
    41 // 对学生的姓名年龄做修改,形参是指针类型
    42 void handleStudent(Student * stu)
    43 {
    44     // stu.setAge(20);    // 这样写是错误的,因为指针类型是地址不是对象,需要“*”取值符来得到地址上面的对象
    45     // stu.setName("lisi");
    46     (*stu).setAge(20);    // 修改指针stu存放地址上面对象的age
    47     (*stu).setName("lisi");    // 修改指针stu存放地址上面对象的name
    48 }
    49 
    50 void Student::setName(string name)
    51 {
    52     this->name = name;
    53 }
    54 
    55 void Student::setAge(int age)
    56 {
    57     this->age = age;
    58 }
    59 
    60 string Student::getName()
    61 {
    62     return this->name;
    63 }
    64 
    65 int Student::getAge()
    66 {
    67     return this->age;
    68 }

    运行结果:

      name = zhangsan
      age = 18
      调用处理方法之后:
      name = lisi
      age = 20

  • 相关阅读:
    1029 旧键盘 (20 分)
    1028 人口普查 (20 分)
    1026 程序运行时间 (15 分
    1025 反转链表 (25 分
    1024 科学计数法 (20 分
    1023 组个最小数 (20 分)
    将命令的输出保存到文件
    使用与管理控制台历史
    度量命令执行时间
    检查最后运行命令的状态
  • 原文地址:https://www.cnblogs.com/baoyz/p/3198542.html
Copyright © 2020-2023  润新知