常对象不能调用普通的成员方法
常对象只能调用常方法
普通对象 能调用常方法
常方法 不能调用普通的成员方法
普通的成员方法可以调用常方法
不能返回局部变量的指向或者引用
返回值规则:
1、类类型 都是以临时量的方式带回(寄存器无法取地址)
2、其他类型(内置类型)<=4字节 由eax寄存器带回 >4 &&<=8字节 由eax和edx寄存器带回 >8字节由临时量带回
如下面的代码:下面的Node类是一个空类
空类可以生成对象并且对象可以调用成员方法 空类占用大小为1(为了能调用Show 要传对象的地址给this指针 类的大小至少为1)
#include<iostream>
using namespace std;
class Node
{
public:
void Show()
{
cout<<"hello world\n"<<endl;
}
};
int main()
{
Node node;
node.Show();
return 0;
}
include<iostream>
using namespace std;
class Test
{
public:
Test(int a=10):ma(a)//构造函数 ma(a)初始化列表 对成员变量进行初始化
{
cout<<"Test::Test(int)"<<endl;
//ma=a;//函数体中是赋值 不是初始化
}
int GetValue()
//&&int GetValue()const 现在的this指针变成 const Test*const 前面的const修饰的是值 后面的修饰的是指向
//常函数 常函数修饰this指针指向的对象不能被修改
{
return ma;
}
~Test()
{
cout<<"Test::~Test()"<<endl;
}
private:
int ma;
};
int main()
{
//const Test test1(20);//常对象 错误 解决办法&&将普通方法变为 常方法
如果 常对象调用了普通的成员方法 this指针将指向常对象的地址
this----->&test1
test*Const---->const test*
普通对象的指针指向常对象 有修改常量对象内存块的风险
//常对象 不能调用普通的成员方法 常对象 只能调用常方法
Test test1(20);//用带有整形参数的构造函数对test1对象进行初始化
int rt=test1.GetValue();//普通的成员方法一定要有对象调用他
&test1---->this; test1的地址给this指针
const Test*--->Test*const
//const int a=10;
//cout<<typeid(a).name()<<endl;//打印a的类型
cout<<rt<<endl;
return 0;
}
class Test
{
public:
Test(int a=10):ma(a)//构造函数 ma(a)初始化列表 对成员变量进行初始化
{
cout<<"Test::Test(int)"<<endl;
//ma=a;//函数体中是赋值 不是初始化
}
int GetValue()const// 现在的this指针变成 const Test*const 前面的const修饰的是值 后面的修饰的是指向
{
//Show();//常方法中不能调用普通的成员方法
return ma;
}
void Show()//普通的成员方法
{
cout<<"ma:"<<ma<<endl;
}
~Test()
{
cout<<"Test::~Test()"<<endl;
}
private:
int ma;
};
//常对象不能调用普通的成员方法
//常对象只能调用常方法
//普通对象 能调用常方法
//常方法不能调用普通的成员方法
//普通的成员方法可以调用常方法
int main()
{
Test test1(20);
int rt=test1.GetValue();
cout<<rt<<endl;
return 0;
}
//Test GetValue(Test rhs)//形参用一个普通对象做形参 生成形参对象rhs
//{
// Test temp=rhs; //局部对象生成 temp 拷贝构造
// return temp;//显示生成临时量 是一个普通的对象 存在内存中
// //以对象类型返回 不管几个字节都是由临时量带回来
//
//}
//Test GetValue(Test& rhs)//实参穿形参过程中没有对象生成
// //对象 、自定义类型做形参 用&的效率高 不仅调用构造还调用析构
// //内置类型直接用值传递
//{
// Test temp=rhs;//局部对象
// return temp;//临时对象
//}
//Test GetValue(Test*prhs)//指针指向形参对象没有对象生成
//{
// Test temp=*prhs;//拷贝构造 生成局部对象
// return temp;//临时对象
//}
//Test GetValue(Test& rhs)
//{
// return Test(rhs);//生成一个对象 代码显示生成临时对象 然后返回出去 还有一个临时对象生成 优化掉
// //return通过rhs之前显示生成临时对象,要吧临时对象返回出去 把return之前的优化掉
//}
//Test& GetValue(Test& rhs)//rhs是对Test的引用 引用没有新对象生成
//{
// return Test(rhs);//返回的是对象的引用 没有临时对象生成
//}
Test& GetValue(Test& rhs)//不能返回局部变量的指向或者引用
{
Test tmp(rhs);
return tmp;
}
int main()
{
Test test1(20);//test1对象
// 1、2 GetValue(test1).Show();// 不能用寄存器返回 寄存器都是不能取地址的 临时对象存放在内存中
//用临时对象返回 调用成员函数 将对象的地址传给this指针
// 3 GetValue(&test1).Show();
// 4 GetValue(test1).Show();
// 6 Test test2=GetValue(test1);//整个过程有两个对象生成 test1 test2有两个被优化掉
Test test2=GetValue(test1);//调用了拷贝构造函数把原来的栈帧覆盖
cout<<test2.ma<<endl;
return 0;
}
#include<iostream>
using namespace std;
class Test
{
public:
Test(int a=10):ma(a)
{
cout<<"Test::Test(int)"<<endl;
}
Test(const Test &rhs):ma(rhs.ma)
{
cout<<"Test::Test(Test)"<<endl;
}
int GetValue()const
{
return ma;
}
void Show()
{
cout<<"ma:"<<ma<<endl;
}
~Test()
{
cout<<"Test::~Test()"<<endl;
}
public:
int ma;
};
void Func()
{
cout<<"hello world!"<<endl;
}
int main()
{
typedef void(*pFunc)();
pFunc pfunc = &Func;
pFunc();
Test test1;
typedef void (Test::*pFunc1)();//函数指针
pFunc1 pfunc1=&Test::Show;
(test1.*pfunc1)();//.*函数指针调用成员函数
//Test test1(20);
//Test*ptest =new Test(30);
//typedef void (Test::*pFunc1)();//函数指针
//pFunc1 pfunc1=&Test::Show;
//(ptest->*pfunc1)();
//delete ptest;
//return 0;
}
explicit 禁止隐式生成临时对象
mutable去除常性
#include<iostream>
using namespace std;
class Test
{
public:
explicit Test(int a,int b=0):ma(a),mb(b)
{
}
private:
int ma;
int mb;
};
int main()
{
Test test1(10,20);
test1=20;//错误 这里隐式生成了临时对象 关键字explicit禁止隐式生成临时对象
return 0;
}