C++参数类型的合理选用

C++参数类型的合理选用

前言

  • 在传统C++中, 函数的参数类型主要有三种: 传值传指针传引用
  • C++11开始,多了一种叫做 右值引用的类型,以及一些智能指针类型(shared_ptrweak_ptrunique_ptr)

各参数类型的最佳适用场景

传值

  • 传值开销 比 传指针和引用开销更小,如: charchar *char &占用内存更小
  • 函数内部明确需要参数的副本

传指针

  • 结构体,体积较大,并且设计到不通类型的地址转换
  • 内存字节操作
  • 参数需要分为空与非空
  • 多个对象内存连续

传引用

  • 单个对象,体积较大
  • 需要对参数对象做修改
  • 函数内明确不能使用空对象

传右值引用

  • 需要将参数对象的所有权转移

传智能指针

  • 需要区分空与非空,并且设计对象生命周期管理的,如:

当参数对象需要共享时,使用 shared_ptr
当参数对象需要独占,只能进行转移时,使用 unique_ptr
参数中不使用 weak_ptr, weak_ptr仅用于共享对象之间的互相引用解决引用环

const约束

  • 当参数明确表示函数内部不会进行修改时,无论是引用类型参数还是指针类型参数,都应该加上 const约束,如:
void funcRef(const Arg& arg)
{
	// 内部不会对arg做任何改动
}

void funcPointer(const Arg *arg)
{
	if (arg == nullptr) {
	} else {
		// 同样不会对arg有任何改动
	}
}

注意:

严格执行必要的参数const约束后会发现,当调用了某些类的成员函数并且这些函数同样不会对自身有任何改动,但却编译不通过。这是为什么呢?

成员函数的const约束

上述问题中的答案其实很简单,因为调用的成员函数虽然没有对成员有改动,但是成员函数并没有标记为const, 没有标记为const的成员函数,只有在对象本身处于非常量状态下才能调用。因此,如果明确表示成员函数不会对成员变量有改动,需要显示的在函数尾部标记为const。如:

class Person {
	explicit Person(const std::string& name):name_(name) {}
	~Person() = default;

	std::string name() const 
	{
		return nane_;
	}
	
	int age() const
	{
		return age_;
	}
private:
	std::string name_;
	int age_ {0};
};

void callPerson(const Person& person)
{
	std::cout << person.name() << ", your turn" << std::endl;
}

常左值引用与右值引用的合并

当某个函数逻辑内部会对参数做副本时,传统做法是使用常引用类型,然后在内部使用拷贝函数显式定义一个副本对象,C++11后,除了要求要写常左值引用版本的参数类型外,还需要实现右值引用版本的参数,保证传入的对象如果是一个右值,则会自动进行移动操作,而不是拷贝

针对上述情况,我们可以将两种情况进行合并,实现一个传值类型的参数版本即可,这样,既可以传左值引用自动拷贝(传值自动拷贝),也可以传右值引用将外部对象直接移动到函数参数内。

将一个右值引用移动到参数上,可以大大减少对象的拷贝开销,增加对象的利用率

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值