C++:对象与函数

一、类对象作为函数形参

类对象作为形参,本质上与基本类型作为形参并无区别。但是考虑到普通类型作为形参,使用的是值传递,也就是将实参值拷贝一份给形参。如果是类对象的话,此时将会调用一个拷贝构造函数。也就是以实参为参数拷贝构造形参。 如果类对象本身特别复杂,这个拷贝过程显然也会更加耗时,如此便会降低程序运行的效率。

class T{
public:
    T(){}
    T(const T&rhs){}
};

void f(T x){}

int main(){
    T a;
    f(a);   //此处会发生一个拷贝构造,也就是用a去拷贝构造x
    return 0;
}

出于效率的考虑,一般对于类类型的形参,一般会使用引用类型。如下:

void f(T& x){}     //形参是T&类型,而不是普通的T类型

另一方面,出于程序健壮性、可读性的考虑,如果f函数并没有改变形参的内容,则还会给形参加上一个 const 修饰。如下:

void f(const T&x){}

 二、对象作为函数返回值:

类对象作为函数返回类型,与基本类型并无不同。而且此处无需考虑效率问题,因为没办法考虑。 如果一定要使用类对象作为参数,出于效率考虑,可以将形参类型设置为类的引用。但是如果函数一定要返回类对象,此时是不能直接使用引用类型的。 考虑加法操作:

Int& add(const Int&a,const Int&b)
{
   Int c = a + b;//假定这个加号操作是可以执行的
   return c;
}

这个函数是错误的,因为其返回的是c的引用。但是c是一个局部变量,当add函数结束后,c就被销毁了。主函数只能得到一个“悬空的”引用,逻辑上是无意义的。 因此,是否返回引用,必须出于函数功能的考虑,而不能出于函数的效率考虑。一般而言,要使返回的引用有意义,需要返回全局变量的引用,或者返回形参的引用(形参本身也必须是引用类型)。如下:

Int& min(const Int&a,const Int&b)
{
    if ( a < b ) return a;//假定这个小于号是可以执行的
    return b;
}

这个函数就是返回的引用,而且逻辑上也是正确的。当然,出于健壮性和可读性的考虑,这里所有的引用都应该使用 const 修饰。

三、类对象作为输出参数

上面提到过,类对象作为参数可以使用引用提高效率,但是类对象作为函数返回值,则无法保证一定可以使用引用。不使用引用直接返回,效率上就会有所影响,特别是类本身非常复杂的情况下。 有另外一种办法,既可以提高效率,又能够“返回”类对象。这就是使用输出参数。 以 add 函数为例,普通的 add 函数声明如下:

 Int add(const Int&lhs,const Int&rhs);

完成 2 个 Int 的加法操作,因此参数数量为 2,返回类型也是 Int。 而使用输出参数的 add 函数则拥有 3 个参数,而且类型是 void。如下:

void add(const Int&lhs,const Int&rhs,Int&ans);

其中第 3 个参数实际上保存的是加法的结果,因此称之为输出参数。这在 C 语言和 C++ 中也是一种常用的编程方法。 同时这里也显示了 const 作为修饰符在代码可读性方面的作用。合理的使用 const 修饰,可以令用户非常清楚的了解个参数的用途。 例如,C 语言中字符串拷贝函数的声明如下:

char* strcpy(char *dest,const char *src);

有了 const,可以非常清楚的看到第二个参数代表源字符串,第一个参数代表目的。 特别要注意一点,不要以为使用参数名进行标识就万事大吉。因为在 C、C++ 以及 Java 中,函数(方法)声明都是不考虑形参名的。也就是形参名本质上不影响函数原型。

你可能感兴趣的:(c++,开发语言)