参考:
重点:
- 智能指针模拟,计数器
运算符重载
- operator->
- operator*
- ++a ,a++,--a ,a--运算符
- operator=
- operator[]
- operator()
- operator double()
- operator bool()
- 函数对象
- 静态数据成员
- const
- 引用
注意:
- 如果有指针类型的类,自己写拷贝构造函数,自己写赋值运算符函数,自己写析构!!!!
正文:
////达内C++教程\03_标准C++编程_陈宗权_7day\标准C++编程_day04PM_运算符重载 TEST1
//#include <iostream>
//#include <string>
//using namespace std;
//
////.*、 .、 三目运算符? :、不能重载
////:: 不能重载
//// == 、 -> 、[] () (类型) 只能用成员函数
//// 运算符首先考虑弄成成员函数
//// T* operator->() 只能无参数,返回对象的地址
//// x->y x.operator->() 封装类型,模仿指针
//
//
//class F {
//
// F operator!()const;
//};
//
//// 临时对象也是对象!!!
//// 只会调用构造函数,不会调用复制构造函数,因为编译做了优化。
//F F::operator!() const
//{
// return F();
//}
//
//struct date {
// int year;
// int month;
// int day;
//};
//struct Person {
// string name;
// int age;
// bool gender;
// double salary;
// date birth;
//
// Person() { cout <<"创建Person对象在"<<this << std::endl; }
// ~Person() { cout << "释放Person对象在" << this << std::endl; }
//};
//
//
//class autoptr {
// Person* p;
// static int cnt;//大家共用1个计数器
//public:
// autoptr(Person* p) :p(p) { ++cnt; }
// autoptr(const autoptr& a) :p(a.p) { ++cnt; }
// ~autoptr() { std::cout <<cnt<<":" << std::endl; if (--cnt == 0) delete p; }
// Person* operator->() { return p; }
// Person& operator*() { return *p; }
//};
//
////静态数据成员在类外初始化
//int autoptr::cnt = 0;
//
//int main()
//{
// //a指针
// //Person* a = new Person;
// autoptr b(new Person);//或者autoptr b= new Person;
//
// autoptr c = b;//初始化,调用复制构造,2个都会析构,第二个析构就会有问题,对指针进行计数,最一个后才进行delete
// autoptr d = b;
// std::cout << b->age << std::endl;
// b->name = "furong";//b.operator->()->name
// std::cout <<(*b).name << std::endl;
// (*b).birth.year = 1985;
// std::cout << b->birth.year << std::endl;
// c = b;//赋值运算符
// system("pause");
//
//}
//问题1:
// 赋值运算符,会原样复制,计数器没有加1。析构不会有问题。
// 答:析构有问题是因为多次delete,而我不会多次delete是因为我用了计数器,因为多个对象的数据指针类型成员指向同一块地址
//
////达内C++教程\03_标准C++编程_陈宗权_7day\标准C++编程_day04PM_运算符重载 TEST2
//#include <iostream>
//#include <string>
//using namespace std;
//
//class Stack {
// typedef unsigned int uint;
// string* mem;
// uint max;
// uint len;
//public:
// Stack(uint n):mem(new string[n]),max(n),len(0) {}
// Stack(const Stack& s) :mem(new string[s.max]),max(s.max),len(s.len) {}//新分配内存空间就不会有问题
// uint max_size() const { return max; }
// uint size() const { return len; }
// Stack& push(const string& e) { if (len >= max) throw 0; mem[len++] = e; return *this; };
// string pop() { if (len == 0) throw 1; return mem[--len]; }
// void print()const { for (uint i = 0; i < len; i++) cout << mem[i]; cout << endl; }
// //去想
// Stack& operator=(const Stack& rh) {
// if (this == &rh) return *this; //考虑自己给自己赋值的情况
// delete[] mem;
// mem = new string[rh.max];
// for (uint i = 0; i < len; i++) { mem[i] = rh.mem[i]; }
// return *this;
// }
//
// ~Stack() { delete[] mem; }
//
//};
////如果有指针类型,自己写拷贝构造函数,自己写赋值运算符函数,自己写析构!!!!
//
//
//int main()
//{
// Stack s1(5);
// Stack s2(8);
// Stack s3(s1);//new一块地方,析构会有问题,重复释放同一块内存,导致
// s1.push("1").push("2").push("3").push("4");
// s1.print();
// s2.push("yangqiang").push("furong");
// s2.print();
// s1 = s2;//析构有问题,赋值之后,2个对象的成员又一样了,s1.operator=(s2)
// s3.print();
//
// //
// s2 = s2;
//
// system("pause");
//}
//
////TEST3
////++a (前++)
////T& operator++(T& a) 非成员
////T& operator++() 成员
//
////a++,(后++) 加个形参,这个形参称为哑元
////T operator++(T& a, int) 非成员
////T operator++(int) 成员
//
////对自定义类型,要用前++ ,因为效率高,少了一些
//#include <iostream>
//using namespace std;
//
//class F {
// int n;
// int d;
//public:
// F(int n = 0, int d = 1) :n(n), d(d) {}
// friend ostream& operator<<(ostream& o, const F& f) {
// cout <<f.n<<"/"<<f.d << endl;
// return o;
// }
// F& operator++() { n += d; return *this; }
// F operator++(int) { F old(*this); n += d; return old; };
// friend F& operator--(F& f) { f.n -= f.d; return f; }
// friend F operator--(F& f, int) { F old(f); f.n -= f.d; return old; }
//
// operator double() { return 1.0*n / d; }
// operator bool() { return n != 0; }
//};
//
//void func1(F a) { cout <<a << endl; }
//
//int main()
//{
// F f1(2, 5), f2(4, 9), f3(17, 3);
// cout << ++f1 << std::endl;//f1.operator++()
// cout << f2++ << std::endl;//f2.operator++(0)
// cout << "f1=" << f1 << ", f2= " << f2 << std::endl;
// cout << --f3 << std::endl;//operator--(f3)
// cout << f3-- << std::endl;//operator--(f3,0)
// cout << f3 << std::endl;
//
// //匿名对象,有点像类型转换,如果只有一个参数,可以看成类型转换(F)3 也是可以的
// cout << F(3) << endl;
//
// cout << double(f1) << endl;//f1.operator double()
// cout <<boolalpha<< bool(f3) << endl;//f1.operator bool()
//
// //实参初始化形参是可以的F a(6);没有问题
// func1(6);
//
// system("pause");
//
//
//}
//TEST4 []
//模仿一个数组
#include <iostream>
using namespace std;
class A {
public:
typedef unsigned int uint;
private:
int * p;
uint n;
public:
A(uint n) :n(n) { p = new int[n]; if (p == NULL) throw 0; memset(p,0,n*4); }//初始化数组的初始值
~A() { delete[] p; }
//必须加const!!!!!!!!!!!!!!!!!!!!!函数体之前加const,一方面是为了不改变成员变量,另一方面是用于常量成员
//越界肯定有问题!!!!!!!!!!!!!!!!!
int& operator[](uint i) const { if (i >= n) throw 1; return p[i]; }//有点像递归,其实不是
int& operator[](const char* c) const
{
//atoi: "123"==>123. 不是整数不知道
int i = atoi(c);
if (i<0||i>=n) throw 1; return p[i];
}//有点像递归,其实不是
uint size() const { return n; }
void operator()(int v) {
for (int i = 0; i < n; i++) {
p[i] = v;
}
}
void operator()(const char* s) {
int v = atoi(s);
for (int i = 0; i < n; i++) {
p[i] += v;
}
}
int operator()(int beg, int delta)
{
for (int i = 0; i < n; i++)
{
p[i] = beg, beg += delta;
}
return p[n - 1];
}
};
ostream& operator<<(ostream& o, const A& a)
{
o << "{";
for (int i = 0; i < a.size(); i++) {
cout << a[i] << " ";
}
o << "}";
return o;
}
int main()
{
A x(5), y(8);
x[2] = 20; y[6] = 66;//x.operator[](2) y.operator[](6)
cout <<"x= "<<x<<",y= "<<y << endl;
x["0"] = 8; y["2"] = 33;
cout << "x= " << x << ",y= " << y << endl;
cout << x[2];
x(3);//x.operator()(3)
cout << x << endl;
y("50");
cout << y << endl;
// 10开始,按2递增.
// 函数对象,很像函数,他可以有很多东西!!!!!
cout<<"last element : "<<x(10,2);//x.operator()(10,2)
cout <<"x= "<< x<<endl;
system("pause");
}
//() 多少目都可以,多目运算符
网友评论