zoukankan      html  css  js  c++  java
  • C++学习之路: class的this隐式指针讨论

    class内部的成员函数是不需要把 自己的 privata元素传入的。因为系统已经通过this指针帮我们传入了。

     1 #include <iostream>
     2 #include <string>
     3 #include <vector>
     4 using namespace std;
     5 
     6 /*
     7  * 本例错误的原因是:set系列函数返回的是对象
     8  * 所以返回时产生了一个临时的对象
     9  */
    10 class Student
    11 {
    12     public:
    13         Student()
    14             :id_(0), name_(""), age_(0)
    15         {
    16             cout << "构造Student" << endl;
    17         }
    18 
    19         ~Student()
    20         {
    21             cout << "销毁Student" << endl;
    22         }
    23 
    24 
    25         Student setId(int id)
    26         {
    27             id_ = id;
    28             return *this;
    29         }
    30 
    31         Student setName(const string name)
    32         {
    33             name_ = name;
    34             return *this;
    35         }
    36 
    37         Student setAge(int age)
    38         {
    39             age_ = age;
    40             return *this;
    41         }
    42 
    43         void print(ostream &os) const
    44         {
    45             os << id_ << " " << name_ << " " << age_ << endl;
    46         }
    47 
    48     private:
    49         int id_;
    50         string name_;
    51         int age_;
    52 };
    53 
    54 
    55 int main(int argc, const char *argv[])
    56 {
    57     Student s;
    58     s.setId(11).setName("zhangsan").setAge(88).print(cout);    //此处通过值拷贝返回了3个局部对象 {id_= 0, Name_ = "", age_ = 0}
    59     s.print(cout);                                             //传入给setId() 返回一个拷贝 ①{id_= 11, Name_ = "", age_ = 0} 
    60                                                                //传入给setName() 值拷贝返回一个局部对象②{id_= 11, Name_ = "zhangsan", age_ = 0} 
    61                                                                //传入给setAge() 值拷贝返回一个局部对象③{id_= 11, Name_ = "zhangsan", age_ = 88} 
    62                                                                
    63 return 0; }
    构造Student
    11 zhangsan 88
    销毁Student
    销毁Student
    销毁Student
    11  0
    销毁Student
    
    //结果打印了销毁了3个局部变量
    
    

    综上,如果不通过返回引用的方式return s,成员函数其实返回的是一个拷贝的副本, 上面我们已经分析过了一共调用了3次成员函数,共返回了3个局部对象,

    分别是:

    ①{id_= 11, Name_ = "", age_ = 0}  是由setId()返回的一个副本
    ②{id_= 11, Name_ = "zhangsan", age_ = 0} 由setName()返回的一个副本
    ③{id_= 11, Name_ = "zhangsan", age_ = 88} 有setAge()返回的一个副本
     

    ##(参考《C与指针》)它们的作用域,是相继屏蔽的。作用域的知识可以参考c与指针

    下面我们尝试使用返回引用的方式,让对象的成员函数返回自身的引用 的正确做法。

     1 #include <iostream>
     2 #include <string>
     3 #include <vector>
     4 using namespace std;
     5 
     6 /*
     7  * 本例演示了,this返回自身引用的正确做法
     8  *
     9  * 同时说明了重载print函数const版本的必要性
    10  */
    11 class Student
    12 {
    13     public:
    14         Student()
    15             :id_(0), name_(""), age_(0)
    16         {
    17             cout << "构造Student" << endl;
    18         }
    19 
    20         ~Student()
    21         {
    22             cout << "销毁Student" << endl;
    23         }
    24 
    25 
    26         Student &setId(int id)
    27         {
    28             id_ = id;
    29             return *this;
    30         }
    31 
    32         Student &setName(const string name)
    33         {
    34             name_ = name;
    35             return *this;
    36         }
    37 
    38         Student &setAge(int age)
    39         {
    40             age_ = age;
    41             return *this;
    42         }
    43 
    44         const Student &print(ostream &os) const     //这一行,如果函数时const版本,那么返回值也必须是const 否则在语义上造成歧义, 编译器会报错
    45         {
    46             os << id_ << " " << name_ << " " << age_ << endl;
    47             return *this;
    48         }
    49 
    50         Student &print(ostream &os)    //此处重载了一个非const版本用于重载
    51         {
    52             os << id_ << " " << name_ << " " << age_ << endl;
    53             return *this;
    54         }
    55 
    56     private:
    57         int id_;
    58         string name_;
    59         int age_;
    60 };
    61 
    62 
    63 int main(int argc, const char *argv[])
    64 {
    65     Student s;
    66     s.setId(11).print(cout).setName("zhangsan").setAge(88).print(cout);
    67     s.print(cout);
    68     return 0;
    69 }

    上述代码我们演示了返回自身引用的 正确做法, 然而 在print打印函数,我们又重载了一个非const的版本,为什么要这么做呢?

    我们知道, 当我们使用对象成员函数时, 如果传入的是一个const常量,那么该常量只能调用cons版本的函数进行处理, 

    输入非常量时,则调用const 和 非const 版本都可以, 

    const 的返回值依然还是const,有时我们不希望它返回一个const常量,而是希望返回一个变量 使得我们可以改变它, 

    由此我们重载了一个非const版本。

  • 相关阅读:
    跟结束进程相关的那些信号
    tcpdump使用示例
    Linux在bash history当中添加timestamp
    CentOS中在/etc/rc.local添加开机自启动项启动失败
    CentOS配置通过DHCP的方式动态获取IP
    CentOS桌面安装
    MySQL二进制安装
    对okhttp参数的一些思考
    依赖倒置原则(DIP)
    Liskov替换原则(LSP)
  • 原文地址:https://www.cnblogs.com/DLzhang/p/3985800.html
Copyright © 2011-2022 走看看