int main()
{
int i = 0;
i = i++ + 1;
cout<<i<<endl;
}
不可重载运算符
运算符 | | |
---|
? : | 三木条件运算符 | | . .* | 成员操作符 | | :: | 作用于操作符 | | sizeof | 类型字长操作符 | |
class Int
{
private:
int value;
public:
Int(int x = 0):value(x)
{
cout << "Create Int:"<<this<<endl;
}
Int(const Int& it):value(it.value)
{
cout << "Copy Create Int:"<<this<<endl;
}
Int& operator=(const Int& it)
{
if(this != &it)
{
value = it.value;
}
cout<<this<< "=" << &it <<endl;
return *this;
}
~Int()
{
cout <<"Destory Int:"<<this<<endl;
}
Int* operator&()
{
return this;
}
const Int* operator&()const
{
return this;
}
Int& operator++()
{
this->value += 1;
return *this;
}//++a;
Int operator++(int)
{
Int old = *this;
++* this;
return old;//返回的旧对象是局部对象,不能返回引用
}
Int& operator--()
{
this->value--;
return *this;
}
Int operator--(int)
{
Int old = *this;
--* this;
return old;
}
Int operator+(const int x)const
{
return Int(this->value+x);
}
};
int main()
{
int i = 0;
i = i++ + 1;//i = 2 g++
cout<<i<<endl;
Int a = 0;
a = a++ + 1;
//a = a.operator++(0)+1;
//a = a.operator++(&a,0).operator+(1);
//a = operator+(&operator++(&a,0),1));
//a.operator=(operator+(&operator++(&a,0),1));
//operator=(&a,operator+(&operator++(&a,0),1));
a.Print();
}
尽量少使用静态量以及少以引用返回
Int& operator++(int)
{
static Int old = *this;//只执行一次,无法更新旧值
old = *this;
++* this;
return old;
}//a++
int main()
{
Int a(10);//value = 10;
Int b = a++;//b.value=10;a.value=11;
Int &c = a++;//c.value=11;a.value=12;
c = c + 100;//111
Int d = a++;//d.value=12;
}
编译器如何对表达式进行编译:
算术表达式通过中缀将其改为后缀表达式
后缀表达式相比于中缀表达式的好处是:
(1)后缀自带运算规则
运算符重载什么情况下以引用返回,什么情况下以值返回?
运算符操作之后,如果返回自身,以引用返回
运算符操作之后,如果返回的是临时量或者将亡值,以值返回
构造函数的任务:
(1)构建对象
(2)对对象进行初始化
(3)类型的转换(单参的构造函数)
class Int
{
private:
int value;
public:
Int(int x,int y = 0):value(x + y)
{
cout << "Create Int:"<<this<<endl;
}
//Int a(1,2);
//int b = 100;
//a = b,20;
//a = (Int)(b,20);//强转,按照类型转换方式产生临时对象,此构造函数必须为单参
//a = Int(b,20);//调动构造函数产生临时对象,产生无名对象,接收的是两个参数
Int(const Int& it):value(it.value)
{
cout << "Copy Create Int:"<<this<<endl;
}
Int& operator=(const Int& it)
{
if(this != &it)
{
value = it.value;
}
cout<<this<< "=" << &it <<endl;
return *this;
}
~Int()
{
cout <<"Destory Int:"<<this<<endl;
}
//重载整形强转运算符
//加const,普通对象和常对象都可以强转
operator int()const
{
return value;
}
//强转运算符的重载不需要返回类型,返回的就是它强转后的类型
};
int main()
{
Int a = 10,b = 20;
a < b;
int x = 100;
a < x;
//强转指的是:a调动强转,把a的value值返回,拿value和x进行比较
return 0;
}
int main()
{
//把数据值给对象
int a(10);
int b = 100;
a = b;
//把对象给数据值
b = a;
b = a.operator int();
b = operator int(&a);
b = (int)a;
}
显式转换,把数据值转为对象
隐式转换,设计的类型为单参,或者某一个参数为0
如果不想让单参的构造函数进行隐式转换,加明确关键字explicit
class Add
{
mutable int value;//可以使value发生改变
public:
Add(int x = 0):value(x){}
int operator()(int a,int b)const
{
value = a + b;
return value;
}
};
int main()
{
int a = 10,b = 20,c = 0;
c = Add()(a,b);
//类型名+括号:调动构造函数产生临时对象或者将亡值对象,调动自己的括号()进行重载,然后a和b相加给c
}
int main()
{
int a = 10,b = 20,c = 0;
Add add;
//重载了括号()的运算符,称之为仿函数
c = add(a,b);//仿函数
c = add.operator()(a,b);
return 0;
}
class Int
{
private:
int value;
public:
Int(int x = 0):value(x)
{
cout << "Create Int:"<<this<<endl;
}
Int(const Int& it):value(it.value)
{
cout << "Copy Create Int:"<<this<<endl;
}
Int& operator=(const Int& it)
{
if(this != &it)
{
value = it.value;
}
cout<<this<< "=" << &it <<endl;
return *this;
}
~Int()
{
cout <<"Destory Int:"<<this<<endl;
}
};
class Object
{
int num;
Int val;
public:
Object(int x,int y)
{
num = x;
val = y;
}
};
int main()
{
Object obj(1,2);
}
创建对象的时机是在哪个时机点?
对于内置类型,初始化列表以及赋值是等同的效果
对于自己设计的类型,初始化列表以及赋值是不相同的效果,赋值会产生对象
class Int
{
private:
int value;
public:
Int(int x = 0):value(x)
{
cout << "Create Int:"<<this<<endl;
}
Int(const Int& it):value(it.value)
{
cout << "Copy Create Int:"<<this<<endl;
}
Int& operator=(const Int& it)
{
if(this != &it)
{
value = it.value;
}
cout<<this<< "=" << &it <<endl;
return *this;
}
~Int()
{
cout <<"Destory Int:"<<this<<endl;
}
int& Value()
{
return value;
}
const int& Value()const
{
return value;
}
};
class Object
{
Int* ip;
public:
Object(Int *s = NULL):ip(s)
{
}
~Object()
{
if(ip != NULL)
{
delete ip;
}
ip = NULL;
}
//int GetIp(){return ip->Value();}
Int& operator*()
{
return *ip;
}
const Int& operator*()const
{
return *ip;
}
Int* operator->()
{
return &**this;
//ip所指向对象的地址
//return ip;
}
const Int* operator->()const
{
//return ip;
return &**this;
}
Object* operator&()
{
return this;
//取本对象的地址
}
};
int main()
{
Object obj(new Int(10));
Int* ip = new Int(10);
(*ip).Value();
(*obj).Value();
ip->Value();
obj-Value();
}
int main()
{
Object obj(1,2);
}
对于类的成员,尽可能拿列表方式构建,这样产生的对象最少,付出的代价最少
按照设计的顺序进行构建
对象成员的构建顺序和声明的顺序保持一致
class Object
{
Int* ip;
public:
Object(Int *s = NULL):ip(s)
{
}
~Object()
{
if(ip != NULL)
{
delete ip;
}
ip = NULL;
}
};
int main()
{
Object obj(new Int(10));
//new:从堆区申请一个空间,调动构造函数对堆区进行构建对象,返回构建对象的地址
}
对对象的生存期自动管理
int fun()
{
Int *ip = new Int(10);
delete ip;
}
int main()
{
fun();
}
int fun()
{
Object obj(new Int(10));
//对对象的生存期自动管理
}
int main()
{
fun();
}
class Int
{
};
class Object
{
int num;
Int val;
};//强关联
//组合,对象和对象之间的包含
class Int
{
};
class Object
{
int num;
Int *ip;
};//弱关联--智能指针
//指向堆区里的ip对象
//如何显示出对ip对象进行的操作:(就和指针一样对它进行相应的操作)---重载两个运算符:*(解引用),直接返回堆区对象;指向运算符(->),直接返回对象地址
class Int
{
};
class Object
{
int num;
Int &val;
};
//强引用关系
对象在内存中如何分布
206)]
class Int
{
};
class Object
{
int num;
Int val;
};//强关联
//组合,对象和对象之间的包含
class Int
{
};
class Object
{
int num;
Int *ip;
};//弱关联--智能指针
//指向堆区里的ip对象
//如何显示出对ip对象进行的操作:(就和指针一样对它进行相应的操作)---重载两个运算符:*(解引用),直接返回堆区对象;指向运算符(->),直接返回对象地址
class Int
{
};
class Object
{
int num;
Int &val;
};
//强引用关系
[外链图片转存中…(img-LxFw3ECV-1647317766207)]
对象在内存中如何分布
|