C++方法调用&&类类型的返回类型&&函数指针

本文深入探讨C++中常对象与常方法的使用规则,解析常对象如何调用方法,以及常方法的限制。同时,文章详细介绍了成员方法调用的上下文和返回值规则,包括局部变量引用的注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

常对象不能调用普通的成员方法
常对象只能调用常方法
普通对象 能调用常方法
常方法  不能调用普通的成员方法
普通的成员方法可以调用常方法

不能返回局部变量的指向或者引用

返回值规则:

                   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;
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值