文章目录
后置++有两个参数
运算符的重载什么时候以引用返回什么时候以值的形式返回
返回的是*this就以引用返回这样可以少创建对象提高效率;
返回的是重载里面新创建的对象就以值的形式返回;
一,构造函数的三个作用:
创建对象,对象初始化,类型转换(要实现类型转换(银是你构造)构造函数只能是单参的构造函数)
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 << "Destroy Int: " << this << endl; }
void Printf()const
{
cout << Value << endl;
}
};
int main()
{
Int a(10);
int b = 100;
a = b;
return 0;
}
如果想不允许这种隐士的类型转换explicit Int(const Int& it) :Value(it.Value)
字只能用于修饰只有一个参数的类构造函数, 它的作用是表明该构造函数是显示的, 而非隐式的, 跟它相对应的另一个关键字是implicit, 意思是隐藏的,类构造函数默认情况下即声明为implicit(隐式).
类型转换
int a;
doublie d=12.34;
a=d;发生了隐式转换,即编译器先把d强制类型转化为一个int类型的临时变量,值为12,然后由这个临时的int类型的变量去赋值给整型a。
class Object
{
int val;
public:
Object(int v=10) :val(v) { cout << "构造函数" << endl; };
~Object() {};
void operator=(const Object& obj)
{
if (&obj != this)
{
val = obj.val;
}
cout << "赋值语句" << endl;
}
};
int main()
{
Object obj;
obj = 100;
return 0;
}
class Int
{
private:
int Value;
public:
Int(int x = 0) :Value(x)
{
cout << "Create Int: " << this << endl;
}
//构造函数的三个作用:创建对象,对象初始化,类型转换
//如果想不允许这种隐士的类型转换explicit Int(const Int& it) :Value(it.Value)
explicit 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 << "Destroy Int: " << this << endl; }
void Printf()const
{
cout << Value << endl;
}
};
int main()
{
Int a(10);
int b = 100;
a = (Int)b;
return 0;
}
变向的将双参认为是单参
class Int
{
private:
int Value;
public:
Int(int x ,int y) :Value(x+y)
{
cout << "Create Int: " << this << endl;
}
//构造函数的三个作用:创建对象,对象初始化,类型转换
//如果想不允许这种隐士的类型转换explicit Int(const Int& it) :Value(it.Value)
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 << "Destroy Int: " << this << endl; }
void Printf()const
{
cout << Value << endl;
}
};
int main()
{
Int a(10,20);
int b = 100;
a = b;
return 0;
}
更改之后
class Int
{
private:
int Value;
public:
Int(int x ,int y=0) :Value(x*y)
{
cout << "Create Int: " << this << endl;
}
//a(10,20);
// int b=100;
// a=b,2;//a=(Int)(b,20)这是强转类型,逗号表达式取,的右边的值
// a=(Int)(b,20)和a=Int(b,20)不一样后者是构造函数产生临时变量
//构造函数的三个作用:创建对象,对象初始化,类型转换
//如果想不允许这种隐士的类型转换explicit Int(const Int& it) :Value(it.Value)
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 << "Destroy Int: " << this << endl; }
void Printf()const
{
cout << Value << endl;
}
};
int main()
{
Int a(10,20);
int b = 100;
a = b;
return 0;
}
class Int
{
private:
int Value;
public:
Int(int x ,int y=0) :Value(x+y)
{
cout << "Create Int: " << this << endl;
}
//a(10,20);
// int b=100;
// a=b,2;//a=(Int)(b,20)这是强转类型,逗号表达式取,的右边的值
// a=(Int)(b,20)和a=Int(b,20)不一样后者是构造函数产生临时变量
//构造函数的三个作用:创建对象,对象初始化,类型转换
//如果想不允许这种隐士的类型转换explicit Int(const Int& it) :Value(it.Value)
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 << "Destroy Int: " << this << endl; }
void Printf()const
{
cout << Value << endl;
}
};
int main()
{
Int a(10,20);
int b = 100;
a = (Int)(b, 100);//必须是单参数的形式
return 0;
}
整形强转符的重载(避免写很多的< >的运算符重载)
class Int
{
private:
int Value;
public:
Int(int x ,int y=0) :Value(x+y)
{
cout << "Create Int: " << this << endl;
}
//a(10,20);
// int b=100;
// a=b,2;//a=(Int)(b,20)这是强转类型,逗号表达式取,的右边的值
// a=(Int)(b,20)和a=Int(b,20)不一样后者是构造函数产生临时变量
//构造函数的三个作用:创建对象,对象初始化,类型转换
//如果想不允许这种隐士的类型转换explicit Int(const Int& it) :Value(it.Value)
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 << "Destroy Int: " << this << endl; }
void Printf()const
{
cout << Value << endl;
}
operator int()const//重载一个整形强转符
{
return Value;
}
};
int main()
{
Int a(10);
int b = 100;
a = (Int)b;
b = a;//b=a.operator int();
b = (int)a;
}
int main()
{
Int a = 10, b = 10;
a < b;
int x = 100;
a < x;
return 0;
}
易变关键字和()运算符的重载
mutable关键字作用:当类或者结构体中的某个变量被mutable关键字修饰时,即便这个结构体或者类被实例化为const类型,其中被mutable修饰的变量仍可以被修改。
class Add
{
private:
mutable int 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;
Add add;
c = add(a, b);//凡是重载了()运动算符就称之为仿函数
//c=add.operator()(a,b)
}
int main()
{
int a=10,b=20,c=30;
c=Add()(a,b);//类型名加()
//含义是调动构造函数产生将亡值对象在调用()运算符的重载赋值给c
}
二,当一个类的成员变量是对象时
不用初始化列表进行初始化
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 << "Destroy Int: " << this << endl; }
void Printf()const
{
cout << Value << endl;
}
};
class Object
{
int num;
Int val;
public:
Object(int x, int y)
//进入该构造函数之前先要调动Int的构造函数产生对象Create Int:XXXXXXX
//进入之后要用y给val赋值再次调用Int的拷贝构造函数产生临时对象Create Int:yyyyyyy
//赋值时调用Int的赋值运算符重载
//析构临时对象Destroy Int:yyyyyyy
//主函数结束先析构obj对象在析构里面的成员对象对象Destroy Int:xxxxxxx
{
cout << "Create Object: " << this << endl;
num = x;
val = y;
}
~Object()
{cout<<"Destroy Object: "<<this<<endl;}
};
int main()
{
Object obj(1, 2);
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 << "Destroy Int: " << this << endl; }
void Printf()const
{
cout << Value << endl;
}
};
class Object
{
int num;
Int val;
public:
Object(int x, int y):num(x),val(y)
{
cout << "Create Object: " << this << endl;
}
~Object()
{
cout << "Destroy Object: " << this << endl;
}
};
int main()
{
Object obj(1, 2);
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 << "Destroy Int: " << this << endl; }
void Printf()const
{
cout << value << 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 ip;
}
const Int* operator->()const
{
return ip;
}
};
int main()
{
Object obj(new Int(10));
//这样写的好处是可以对Int这个对象的生存期实现自动化
(*obj)->Value();//使用了*运算符的重载
obj->Value();//->运算符重载
}
组合
1,强关联
2,弱关联
3,强引用
何为自动化管理
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 << "Destroy Int: " << this << endl; }
void Printf()const
{
cout << value << 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;
//*this是obj对象然后是obj的*重载的调用
//return ip;
}
const Int* operator->()const
{
return &**this;
//return ip;
}
};
int main()
{
Object obj(new Int(10));
//这样写的好处是可以对Int这个对象的生存期实现自动化,当程序结束时会自己调用析构函数
Int* p = new Int(10);//这个必须手动的delete否则内存泄漏;
(*p).Value();//*p是对裸指针p的解引用
(*obj).Value();//*obj是obj对*运算符重载的调用
ip->Value();//裸指针的直接运用
obj->Value();//obj对->运算符重载的调用
}