zoukankan      html  css  js  c++  java
  • 构造

    
    
    #include<iostream>
    using namespace std;
    class Vector
    {
        int x,y;
    public:
        Vector(){};//默认构造函数
        Vector(int x1,int y1)//重载构造函数
        {
            x=x1;y=y1;
        }
        Vector operator+(Vector v)//成员函数方式重载运算符"+"
        {
            Vector tmp;//定义一个tmp对象
            tmp.x=x+v.x;
            tmp.y=y+v.y;
            return tmp;//返回tmp对象
        }
        Vector operator-(Vector v)//成员函数方式重载运算符"-"
        {
            Vector tmp;//定义一个tmp对象
            tmp.x=x-v.x;
            tmp.y=y-v.y;
            return tmp;//返回tmp对象
        }
        void display()
        {
            cout<<"("<<x<<","<<y<<")"<<endl;
        }
    };
    void main()
    {
        Vector v1(6,8),v2(3,6),v3,v4;
        cout<<"v1=";
        v1.display();
        cout<<"v2=";
        v2.display();
        v3=v1+v2;
        cout<<"v1+v2=";
        v3.display();
        v4=v1-v2;
        cout<<"v1-v2=";
        v4.display();
        system("pause");
    }
    //-------------
    #include<iostream>
    using namespace std;
    class Vector1
    {
        int x,y;
    public:
        Vector1(){};
        Vector1(int x1,int y1){x=x1;y=y1;}
        friend Vector1 operator+(Vector1 v1,Vector1 v2)//友元函数方式
        {
            Vector1 tmp;
            tmp.x=v1.x+v2.x;
            tmp.y=v1.y+v2.y;
            return tmp;
        }
        friend Vector1 operator-(Vector1 v1,Vector1 v2)//友元函数方式
        {
            Vector1 tmp;
            tmp.x=v1.x-v2.x;
            tmp.y=v1.y-v2.y;
            return tmp;
        }
        void display()
        {
            cout<<"("<<x<<","<<y<<")"<<endl;
        }
    };
    void main()
    {
        Vector1 v1(6,8),v2(3,6),v3,v4;
        cout<<"v1=";
        v1.display();
        cout<<"v2=";
        v2.display();
        v3=v1+v2;
        cout<<"v1+v2=";
        v3.display();
        v4=v1-v2;
        cout<<"v1-v2=";
        v4.display();
        system("pause");
    }
    //------------------
    /*bool operator<(const Date1 d1)
        bool operator>(const Date1 d1)
        bool operator==(const Date1 d1)*/
    #include<iostream>
    using namespace std;
    class  Date1
    {
        int year;int month;int day;
    public:
        Date1(){};//默认构造函数,第一个没用,系统预留
        Date1(int y,int m,int d)//重载构造函数
        {
            year=y;month=m;day=d;
        }
        Date1(const Date1 &d1)//复制构造函数,第三个函数好像是复制第二个函数里面的
        {
            year=d1.year;
            month=d1.month;
            day=d1.day;
        }
        bool operator<(const Date1 d1)
        {
            if((year<d1.year)||(year=d1.year&&month<d1.month)||(year==d1.year&&month==d1.month&&day<d1.day))
                return true;
            else
                return false;
        }
        bool operator==(const Date1 d1)
        {
            if(year==d1.year&&month==d1.month&&day&&d1.day)
                return true;
            else
                return false;
        }
        bool operator>(const Date1 d1)
        {
            if((year>d1.year)||(year=d1.year&&month>d1.month)||(year==d1.year&&month==d1.month&&day>d1.day))
                return true;
            else
                return false;
        }
        void disp()
        {
            cout<<year<<"."<<month<<"."<<day<<endl;
        }
    };
    void main()
    {
        Date1 d1(2008,10,1),d2(2010,10,1),d3(d1);
        cout<<"d1:";
        d1.disp();
        cout<<"d2:";
        d2.disp();
        cout<<"d3:";
        d3.disp();
        cout<<"d1<d2:"<<(d1<d2)<<endl;
        cout<<"d1>d2:"<<(d1>d2)<<endl;
        cout<<"d1==d2:"<<(d1==d2)<<endl;
        cout<<"d1==d3:"<<(d1==d3)<<endl;
        system("pause");
    }
    //-----------------
    
    
    
      1operator+ 一般可以间接的通过operator+=来实现 2008-05-05 17:51:43
      2 分类: C/C++
      3 小技巧:operator+ 一般可以间接的通过operator+=来实现
      4 
      5 class Matrix {
      6 public:
      7     Matrix& operator+=(const Matrix& rhs) {
      8         // ...
      9         return *this;
     10     }
     11 
     12     const Matrix operator+ (const Matrix& rhs) const {
     13         Matrix tmp(*this);      // 调用拷贝构造函数,通过复制产生一个新的object
     14         tmp += rhs;             // 利用operator += 实现operator +
     15         return tmp;             // 返回计算结果
     16     };
     17 };
     18 
     19 
     20 
     21 
     22 看下面的代码:
     23 int func(int j) {
     24     int i = 30;
     25     i += j;
     26     return i;
     27 }
     28 这个函数很简单,大家也都认为它没有语法错误。函数返回时,变量i会被销毁,但是函数仍然成功的将i的值返回出来了。呵呵,有点神奇。类比一下:
     29     const Matrix operator+ (const Matrix& rhs) const {
     30         Matrix tmp(*this);      // 调用拷贝构造函数,通过复制产生一个新的object
     31         tmp += rhs;             // 利用operator += 实现operator +
     32         return tmp;             // 返回计算结果
     33     };
     34 函数返回时,变量tmp会被销毁,但是函数仍然可以成功的将tmp的值返回出来。
     35 
     36 注意这句return tmp;其中所隐藏的程序行为。函数返回一个值时,先把要返回的值复制一份(调用copy constructor,拷贝构造函数),放到别处,然后再销毁函数中各种需要销毁的变量,再将控制权交还给函数的调用者,调用者看到的返回值实际上是复制的值。
     37 
     38 举例来说。比如我写
     39 Matrix m = m1 + m2;
     40 则m1+m2会调用Matrix::operator +(函数),函数返回时,先将返回值复制一份(调用copy constructor,拷贝构造函数),然后销毁函数中的变量tmp。函数返回后,利用复制好的值对变量m进行构造。当Matrix m = m1 + m2;这一整条语句都执行完毕后,m1+m2得到的值因为是临时值,不再使用,所以进行销毁,也就是说在这个时候把复制的值销毁。
     41 这样看来,短短的一句Matrix m = m1 + m2;就要产生多个对象并进行销毁。(第一个:operator +中的tmp对象,第二个:返回时需要复制产生一个临时对象,第三个:正式需要的对象m)构造函数和析构函数被大量的调用,效率较低。这种情况下,编译器一般会对其进行优化,尽可能产生较少的对象,减少构造函数和析构函数的调用。但是最终要产生多少对象,这完全取决于编译器的优化能力:有的编译器可能完全不优化,产生三个对象;有的编译器则只产生两个对象(返回时复制一份的对象本身就是上一层函数的变量m);最理想的情况就是只产生一个对象(变量tmp,返回时复制一份的对象,上一层函数的变量m三者合一)。
     42 可以做这样一个实验,定义一个类,在构造函数、拷贝构造函数、析构函数中分别输出不同的信息(例如cout << "construct" << endl;),然后定义一个函数来返回这个类的对象。可以看到不同的编译器可能输出不同的结果。
     43 #include <iostream>
     44 using namespace std;
     45 class Test {
     46 public:
     47     Test()            { cout << "construct" << endl; }
     48     Test(const Test&) { cout << "copy construct" << endl; }
     49     ~Test()           { cout << "descruct" << endl; }
     50 };
     51 Test func() {
     52     Test t;
     53     return t;
     54 }
     55 int main() {
     56     Test t = func();
     57     return 0;
     58 }
     59 
     60 我用vc2005测试,debug模式构造了两个对象(输出四行),release模式则只构造了一个对象(输出两行)。
     61 
     62 注意以下几种用法是错误或者不推荐的。
     63 1. 返回即将被销毁的变量的引用。错误的做法。因为变量被销毁,引用它也就没有意义。
     64 2. 返回指向即将被销毁的变量的指针。错误的做法。理由同上。
     65 3. 通过new分配内存并创建对象,返回它的引用或返回指向它的指针。不推荐。例如:
     66 Matrix m = (m1 + m2) + m3;
     67 则m1+m2的结果一直保存着,无法进行释放。
     68 必须写:
     69 Matrix* pTemp1 = &(m1 + m2);
     70 Matrix* pTemp2 = &(*pTemp1 + m3);
     71 m = *pTemp2;
     72 delete pTemp1;
     73 delete pTemp2;
     74 这种烦琐的方式显然不是我们想要的。
     75 4. 定义一个static变量,返回它的引用或返回指向它的指针。不推荐。
     76 Matrix m = m1 + m2;           // 没问题
     77 Matrix m = (m1+m2) + (m3+m4); // 错误
     78 因为用了static,每次相加的结果都是放到同一个变量中进行保存的。C++没有规定到底先计算m1+m2还是先计算m3+m4。如果先计算m1+m2,则后来计算m3+m4时就会把m1+m2的结果覆盖;如果先计算m3+m4,则后来计算m1+m2时就会把m3+m3的结果覆盖,无论怎么计算,最后都无法得到正确的结果。
     79 
     80 引用:
     81 不过,拷贝构造函数,operator =操作符,还有析构函数一般都要一起出现。
     82 假如其中一个可以不要,那么一般三个都可以不要。
     83 
     84 如果不定义自己的拷贝构造函数、operator =、析构函数,则C++编译器会自动产生一个默认的。实际使用时,先考虑使用默认的拷贝构造函数、operator=、析构函数是否满足需要,如果不满足,就自己定义之。通常,如果成员中使用了指针,就需要自己定义。
     85 
     86 最后,operator +返回的类型要加上const。这是为了避免出现下面的情况:
     87 (m1 + m2) = m3;
     88 如果m1+m2是一个Matrix类型,则它可以被赋值(调用operator=),但是上面的语句是不合逻辑的,不应该被允许。只要让m1+m2是一个const Matrix类型,就可以让上面的语句编译出错。从而避免这种不合逻辑的写法。
     89 
     90 
     91 
     92 小结:
     93 编写加法运算符,最合理的实现可能就是这个了:
     94     const Matrix operator+ (const Matrix& rhs) const {
     95         Matrix tmp(*this);      // 调用拷贝构造函数,通过复制产生一个新的object
     96         tmp += rhs;             // 利用operator += 实现operator +
     97         return tmp;             // 返回计算结果
     98     };
     99 程序必须先追求正确,然后才能追求高效。从上面四种不推荐的情况来看,返回引用或者指针都不是好的做法(有些做法是错误的,有些做法隐含了潜在错误),因此只好返回实际的对象了。
    100 通过编译器的优化,返回一个对象的效率并没有大家想象的那么不堪,实际构造对象的个数往往并不多。没有必要为了这点性能去担忧。
    101 
    102 
    103 
    104 
    105 #include<iostream>
    106 using namespace std;
    107 class MyClass2
    108 {
    109     int n;
    110 public:
    111     MyClass2(int i){n=i;}
    112     operator ++(){n++;}//vc6.0支持,vs2012不支持
    113     operator++(int){n+=2;}
    114     void display()
    115     {
    116         cout<<"n="<<n<<endl;
    117     }
    118 };
    119 void main()
    120 {
    121     MyClass2 A(5),B(5);
    122     A++;
    123     ++B;
    124     A.display();
    125     B.display();
    126     system("pause");
    127 }
    128 #include<iostream>
    129 using namespace std;
    130 class MyClass2
    131 {
    132     int n;
    133 public:
    134     MyClass2(int i){n=i;}
    135     const int operator ++(){n++;return n;}
    136     const int operator++(int){n+=2;return n;}
    137     void display()
    138     {
    139         cout<<"n="<<n<<endl;
    140     }
    141 };
    142 void main()
    143 {
    144     MyClass2 A(5),B(5);
    145     A++;
    146     ++B;
    147     A.display();
    148     B.display();
    149     system("pause");
    150 }
  • 相关阅读:
    第1组 团队Git现场编程实战
    第二次结对编程作业
    团队项目-需求分析报告
    团队项目-选题报告
    第一次结对编程作业
    第一次个人编程作业
    第一次博客作业
    2019 SDN上机第二次作业
    2019 SDN上机第一次作业
    软件工程第五次作业
  • 原文地址:https://www.cnblogs.com/herizai/p/3101528.html
Copyright © 2011-2022 走看看