Page's Personal Website

C++指针和引用作为参数的一些思考

2016-05-03
c++

[TOC]

关于函数传递指针和引用的一些思考


这样写更好

先看几段代码

  • 1.以对象作为参数

参考代码:

void KCore::SetTongList(TongViewInfo info)
{
	m_info = info;
}
  • 2.以指针作为参数

参考代码:

void KCore::SetTongList(const TongViewInfo* info)
{
	if(info)
		m_info = *info;
}
  • 3.以引用作为参数

参考代码:

void KCore::SetTongList(const TongViewInfo& info)
{
	m_info = info;
}

分析:

  • 知道c++类的构造拷贝函数,就知道选择第2和第3种方式,而不要选择第1种方式。因为第1种方式在作为实参的时候就已经进行过一次复制了。多了一次构造和析构函数的消耗,如果类对象内部还有其他对象的话,这个数字会一直高下去
  • 那么第2种和第3种方式有什么样的区别呢?消耗上已经没有区别了,那么区别就在于引用和指针的区别了。举例一种情况就是:如果传过来的参数需要判断是否为nil的时候,选择指针!因为引用没有办法做到这一点,没有空引用一说。关于指针和引用的区别还有网上有很多,到此为止。

延伸

vector

问题:

  1. 针对上述问题,vector是否和一般c++类一样?
  2. vector的assign函数和构造拷贝函数哪个效率更高?
  3. 那么,一般来说stl是否也都是一样呢?

思考

  • 如果vector也支持构造拷贝函数,那么从理论上来说也就是有消耗的。写了一个简单的代码,c++支持vector的赋值操作,并且的确是拷贝了一份

测试代码(linux):

#include<iostream>
#include<vector>

using namespace std;

int main()
{
    	// vector
    	vector<int> vec(2, 5);
    	vector<int> vec2 = vec;
    	vec2[0] = 3;

    	cout << "vec 1: ";
    	for(vector<int>::iterator it = vec.begin(); it != vec.end(); ++it)
           		cout << *it << ",";
    	cout << endl;

    	cout << "vec 2: ";
    	for(vector<int>::iterator it = vec2.begin(); it != vec2.end(); ++it)
           		cout << *it << ",";
   	 	cout << endl;

    	return 0;
}

打印结果:

vec 1: 5,5,
vec 2: 3,5,

总结

  • 《effective c++》条款20建议两条:
    • (1)尽量以pass-by-reference-to-const替换pass-by-value。前者通常比较高效,并可避免切割问题(slicing problem)
    • (2)以上规则并不适用于内置类型,以及STL的迭代器和函数对象。对它们而言,pass-by-value往往比较适当
  • 针对指针和引用的区别,看是否存在为空的需求作为参考;
  • stl的容器也是和c++对象一致。

Similar Posts

Comments