zoukankan      html  css  js  c++  java
  • C++ 中的返回值

    C++中大致有三种返回值:值拷贝(副本),值引用和指针,返回什么类型的值要根据当时情况而定。

    如果返回的是大型对象的副本,那么在每一次的函数调用后返回,都会调用该对象类型的拷贝构造函数构造一个新的副本,这是一个耗时的过程。

    因此在不需要返回对象副本的时候,尽量返回对象的引用或者指针,与此同时,如果不会改变引用或者指针指向的对象的内容,都加上const限定符。

    不论是返回拷贝,引用还是指针,返回值都会作为左值来使用,因此也可以将返回值赋值给其他变量(类型可以是值类型,引用类型或者指针类型)

    实例:

    class Widget 
    {
    public:
    	Widget() 
    	{
    		a = 0;
    		printf("Widget constructor with default value: this:%p a:%d 
    ", this, a);
    	}
    	Widget(int v)
    	{
    		a = v;
    		printf("Widget constructor with parameters: this:%p a:%d 
    ", this, a);
    	}
    	Widget(const Widget& widget)
    	{
    		this->a = widget.a;
    		printf("Widget copy constructor with reference: this:%p widget:%p a:%d 
    ", this, &widget, a);
    	}
    	Widget(const Widget* widget) 
    	{
    		this->a = widget->a;
    		printf("Widget copy constructor with pointer: this:%p widget:%p a:%d 
    ", this, widget, a);
    	}
    	Widget& operator = (const Widget& widget) 
    	{
    		this->a = widget.a;
    		printf("Widget operator =: this:%p widget:%p a:%d 
    ", this, &widget, a);
    		
    		return *this;
    	}
    	Widget& operator + (const Widget& widget)
    	{
    		this->a += widget.a;
    		printf("Widget operator +: this:%p widget:%p a:%d 
    ", this, &widget, a);
    
    		return *this;
    	}
    	Widget getByCopy()
    	{
    		printf("Widget get object by copy: this:%p a:%d 
    ", this, a);
    
    		return *this;
    	}
    	Widget& getByRef()
    	{
    		printf("Widget get object by ref: this:%p a:%d 
    ", this, a);
    
    		return *this;
    	}
    	Widget* getByPointer()
    	{
    		printf("Widget get object by pointer: this:%p a:%d 
    ", this, a);
    
    		return this;
    	}
    
    	int a;
    };
    int _tmain(int argc, _TCHAR* argv[])
    {
    	Widget w1(1); // 调用构造函数 Widget(int v)
    	Widget w2(2);
    	Widget w3; // 调用默认构造函数
    	w3 = (w1 + w2); // 先调用+操作符,在调用=操作符
    
    	printf("
    ");
    	printf("w4 -------------------- 
    ");
    	w3.getByCopy(); // 返回副本
    	printf("w4_1 -------------------- 
    ");
    	Widget w4_1 = w3.getByCopy(); // 感觉应该会有两次拷贝,实际只有一次Widget(const Widget& widget)拷贝构造函数的调用,估计是编译器的优化
    	printf("w4_2 -------------------- 
    ");
    	Widget w4_2;
    	w4_2 = w3.getByCopy(); // 先调用Widget(const Widget& widget)拷贝构造函数,再调用=赋值拷贝函数
    	printf("w4_3 -------------------- 
    ");
    	Widget& w4_3 = w3.getByCopy(); // 调用一次Widget(const Widget& widget)拷贝构造函数
    	printf("-------------------- 
    
    ");
    
    	printf("w5 -------------------- 
    ");
    	w3.getByRef(); // 返回引用
    	printf("w5_1 -------------------- 
    ");
    	Widget w5_1 = w3.getByRef(); // 调用一次Widget(const Widget& widget)拷贝构造函数
    	printf("w5_2 -------------------- 
    ");
    	Widget w5_2;
    	w5_2 = w3.getByRef(); // 没有调用拷贝构造函数,调用一次=赋值拷贝函数
    	printf("w5_3 -------------------- 
    ");
    	Widget& w5_3 = w3.getByRef(); // 直接赋值给引用
    	printf("-------------------- 
    
    ");
    
    	printf("w6 -------------------- 
    ");
    	w3.getByPointer(); // 返回指针
    	printf("w6_1 -------------------- 
    ");
    	Widget w6_1 = w3.getByPointer(); // 调用一次Widget(const Widget* widget)拷贝构造函数
    	printf("w6_2 -------------------- 
    ");
    	Widget w6_2;
    	w6_2 = w3.getByPointer(); // 由于没有针对指针的赋值拷贝函数,先调用拷贝构造函数,创建一个临时变量,再调用=赋值拷贝函数
    	printf("w6_3 -------------------- 
    ");
    	Widget* w6_3 = w3.getByPointer(); // 直接赋值给指针
    	printf("-------------------- 
    ");
    
    	getchar();
    
    	return 0;
    }
    

    运行结果:

    Widget constructor with parameters: this:0035FB70 a:1
    Widget constructor with parameters: this:0035FB64 a:2
    Widget constructor with default value: this:0035FB58 a:0
    Widget operator +: this:0035FB70 widget:0035FB64 a:3
    Widget operator =: this:0035FB58 widget:0035FB70 a:3
    
    w4 --------------------
    Widget get object by copy: this:0035FB58 a:3
    Widget copy constructor with reference: this:0035F9FC widget:0035FB58 a:3
    w4_1 --------------------
    Widget get object by copy: this:0035FB58 a:3
    Widget copy constructor with reference: this:0035FB4C widget:0035FB58 a:3
    w4_2 --------------------
    Widget constructor with default value: this:0035FB40 a:0
    Widget get object by copy: this:0035FB58 a:3
    Widget copy constructor with reference: this:0035FA08 widget:0035FB58 a:3
    Widget operator =: this:0035FB40 widget:0035FA08 a:3
    w4_3 --------------------
    Widget get object by copy: this:0035FB58 a:3
    Widget copy constructor with reference: this:0035FB28 widget:0035FB58 a:3
    --------------------
    
    w5 --------------------
    Widget get object by ref: this:0035FB58 a:3
    w5_1 --------------------
    Widget get object by ref: this:0035FB58 a:3
    Widget copy constructor with reference: this:0035FB1C widget:0035FB58 a:3
    w5_2 --------------------
    Widget constructor with default value: this:0035FB10 a:0
    Widget get object by ref: this:0035FB58 a:3
    Widget operator =: this:0035FB10 widget:0035FB58 a:3
    w5_3 --------------------
    Widget get object by ref: this:0035FB58 a:3
    --------------------
    
    w6 --------------------
    Widget get object by pointer: this:0035FB58 a:3
    w6_1 --------------------
    Widget get object by pointer: this:0035FB58 a:3
    Widget copy constructor with pointer: this:0035FAF8 widget:0035FB58 a:3
    w6_2 --------------------
    Widget constructor with default value: this:0035FAEC a:0
    Widget get object by pointer: this:0035FB58 a:3
    Widget copy constructor with pointer: this:0035FA14 widget:0035FB58 a:3
    Widget operator =: this:0035FAEC widget:0035FA14 a:3
    w6_3 --------------------
    Widget get object by pointer: this:0035FB58 a:3
    --------------------
    

      

  • 相关阅读:
    Day01 基本SQL SELECT
    Java IO流
    排序: 选择排序
    Java的数据存储机制
    Java反射基础笔记
    学习面向对象的三条主线之三 面向对象的三大特征 关键字
    学习面向对象的三条主线之二 面向对象的三大特征
    Oracle数据库知识积累
    office技巧
    如何读书
  • 原文地址:https://www.cnblogs.com/iRidescent-ZONE/p/5468789.html
Copyright © 2011-2022 走看看