您现在的位置是:主页 > news > 阿里巴巴建设电子商务网站目的/昆明排名优化

阿里巴巴建设电子商务网站目的/昆明排名优化

admin2025/5/9 12:31:54news

简介阿里巴巴建设电子商务网站目的,昆明排名优化,做网站建设的,wordpress登录卡死条款20:宁以pass-by-reference-to-const替换pass-by-value 缺省情况下C以by value方式(一个继承自C的方式)传递对象至(或来自)函数。除非你另外指定,否则函数参数都是以实际实参的复件为初值,调…

阿里巴巴建设电子商务网站目的,昆明排名优化,做网站建设的,wordpress登录卡死条款20:宁以pass-by-reference-to-const替换pass-by-value 缺省情况下C以by value方式(一个继承自C的方式)传递对象至(或来自)函数。除非你另外指定,否则函数参数都是以实际实参的复件为初值,调…

条款20:宁以pass-by-reference-to-const替换pass-by-value

缺省情况下C++以by value方式(一个继承自C的方式)传递对象至(或来自)函数。除非你另外指定,否则函数参数都是以实际实参的复件为初值,调用端获得的亦是函数返回值的一个复件。复件(副本)的产生需要花费时间,浪费资源,参看如下代码。

#include <iostream>
#include <string>
using namespace std;
class Base{
public:Base(){cout << "=====Base的构造函数=====" << endl;}Base(int aa, int bb) :a(aa), b(bb){cout << "=====Base的构造函数=====" << endl;}virtual void show()const{cout << a << " " << b << endl;}virtual ~Base(){cout << "=====Base的析构函数=====" << endl;}
private:int a;int b;
};
class Derived :public Base{
public:Derived(){cout << "=====Derive的构造函数=====" << endl;}Derived(int a, int b):Base(a,b){cout << "=====Derive的构造函数=====" << endl;}virtual void show()const {cout << "子类Derived函数中的show()" << endl; Base::show();}virtual ~Derived(){cout << "=====Derive的析构函数=====" << endl;}
};
void hello(Base b){cout << endl;cout << "=====hello=====" << endl;b.show();cout << "---------------" << endl;
}int main(){Base b(1, 2);hello(b);return 0;
}

运行结果如下:
这里写图片描述
可以发现Base析构函数执行了两次,其实其构造函数也执行了两次,因为通过值传递的过程中,我们可以发现,没进行一次值的copy就进行了一次值的copy过程,因此,在函数结束的时候析构函数自动执行,需要析构两个函数,因此需要析构两个对象,因此出现了两个析构函数;
可以看到上面的这种行为需要对参数进行拷贝,浪费资源,同时又降低了程序执行的效率!

那么我们有什么方法可以避免这种问题呢? 当然有的,就是pass by reference-to-const: 这种方式有两种优点:

1)极大提高了程序的执行效率,没有任何构造函数或者析构函数被调用,因为没有任何新对象被创建,一般我们传递的时候应该声明为const变量,这样会保证传递进去的引用变量不会被修改; 2)用pass-by-reference凡是传递参数也可以避免slicing(对象切割)问题。当一个derived class对象通过pass-by-name方式传递的时候被视为一个base class对象,base class的copy构造函数会被调用,导致“对象的行为向derived class对象”的那些特性全被切割掉了,仅仅留下一个base class对象,这种坑让程序开发者陷入深入思考却不知道错在哪里,因此我们推荐使用pass-by-reference-const进行参数传递,参看如下代码:

#include <iostream>
#include <string>
using namespace std;
class Base{
public:Base(){}Base(int aa, int bb) :a(aa), b(bb){}virtual void show()const{cout << a << " " << b << endl;}virtual ~Base(){}
private:int a;int b;
};
class Derived :public Base{
public:Derived(){}Derived(int a, int b):Base(a,b){}virtual void show()const {cout << "子类Derived函数中的show()" << endl; Base::show();}virtual ~Derived(){}
};
void hello(Base b){cout << endl;cout << "=====hello=====" << endl;b.show();cout << "---------------" << endl;
}
void hello2(const Base& b){cout << endl;cout << "=====hello2=====" << endl;b.show();cout << "---------------" << endl;
}
void hello3(Base* b){cout << "=====hello3=====" << endl;b->show();cout << "---------------" << endl;
}
int main(){Derived d(1, 2);hello(d);hello2(d);Base* b = new Derived(2, 3);hello3(b);delete b;return 0;
}

运行结果:
这里写图片描述

这里有一个逻辑坑,内置类型一般通过pass-by-value传递,因为pass-by-reference实际是通过指针传递的,对于内置类型而言,pass-by-value显然效率高一些,同时,内置类型的结构比较小,因此有的人想当然的认为小型types都是pass-by-value传递,甚至它们是用户自定义的class也无所谓,这个结论是错误的!因为有不同的类,同时编译器有不同的工作方式,因此,明智的选择是尽量采用pass-by-reference-const传递,但有特例,对于内置类型、STL的迭代器和函数对象,使用pass-by-value可能效率高一些!
总结:
1)尽量使用pass-by-reference-to-const替换pass-by-value,前者通常比较高效率,并可以避免对象切割问题;
2)以上规则并不适用于内置类型、STL迭代器和函数对象,对他们而言,pass-by-reference往往比较适当!

PS:
1、C++内置类型
算数类型:字符、整数、bool、浮点;
空类型:void。
2、C++STL迭代器:
包括Input iterator、Output iterator、Forward iterator、Bidirectional iterator、Random access iterator这5中迭代器。
3、C++函数对象:

class A{
public:A();...int operator()(int x){return x;}
private:int x;
};
A a(5);
a(10);

此时,a(10)就是函数对象,类似于这种的都是函数对象。