#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");
}
//-----------------
1 :operator+ 一般可以间接的通过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 }
原文链接: https://www.cnblogs.com/herizai/archive/2013/05/27/3101528.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/90158
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!