int main()
{
int i = 0;
i = i++ + 1;
cout<
不可重载运算符
运算符 ? : 三木条件运算符 . .* 成员操作符 :: 作用于操作符 sizeof 类型字长操作符
class Int
{
private:
int value;
public:
Int(int x = 0):value(x)
{
cout << "Create Int:"<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<
尽量少使用静态量以及少以引用返回
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:"<
显式转换,把数据值转为对象
隐式转换,设计的类型为单参,或者某一个参数为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:"<
创建对象的时机是在哪个时机点?
对于内置类型,初始化列表以及赋值是等同的效果
对于自己设计的类型,初始化列表以及赋值是不相同的效果,赋值会产生对象
class Int
{
private:
int value;
public:
Int(int x = 0):value(x)
{
cout << "Create Int:"<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)]
对象在内存中如何分布



