引用 拷贝构造 赋值语句

1、引用

C++中有一种新的数据类型,对已开辟空间在取一个名字;

就是别名,不开辟新的空间,没有空引用

例:int &b; 错误,

交换两个数字用引用实现:

常见的几种引用形式:

(1)、对变量引用:int a = 10;

int &b = a;

(2)、对指针引用:int *p = &a;

int *&q = p;

(3)、对数组引用:int ar[3] = {1, 2, 3,};

int (&b)[3] = ar;

此外还有以下类型的引用:

(1)、常引用 const int x = 100;

int &y = x;        错的,非常量的不能引用常量,只有自己也加上const成为常量才可以引用。

 常量只能常引用;

(2)、     int n = 20;

const int &m = n;   对的,常量引用非常量可以,因为你可以改变,我要求自己不能改变而已!

  变量也可以常引用;

    `    (3)、    const double d = 12.34;

const int &f = d;                对的,此时d和f由于不是同一种数据类型,所以地址不一样,此时f引用的不是真实的d,而是对产生的临时变量的引用(此时会把整数截取);

(4)、     double d = 12.34;

int &f = d;           错的,临时变量一般都具备常量的性质,我们往往在类型转换时所产生的中间临时变量具备常量的性质;所以要加const,对常量的引用,

加上const后,常引用对常量,因为中间的临时变量都是常量(在类型转换时会产生中间的临时变量);只要类型不同,就都会转换;

2、拷贝构造函数

 (1)、对象初始化对象,调用拷贝构造函数。

Test(const Test &t){}

因为拷贝构造函数也是构造函数,所以和类名相同。

const只是为了保护t不被更改;

 &必须加上,因为 Test t(t1);此时相当于t1给t初始化,调用拷贝构造函数,将陷入无穷的递归当中,所以要使用引用;

(2)、拷贝构造函数系统会有默认的,按其成员进行拷贝!

(3)、调用拷贝构造函数的三种场合:  初始化对象时,Test t(t1); 和 Test t = t1;

形参实参传递时

返回值为对象时,会创建一个无名的临时变量,(此时相当于对象给对象赋值);

3、赋值语句

赋值语句系统也有默认的,是各成员之间相互赋值。

void operator=(const Test t);

赋值语句在对象赋值时调用,可以说是对=的重载;

此时const只是为了保护不被修改,t调用拷贝构造函数(对象给对象初始化赋值),但是为了时间和空间的效率,此处用引用更好;

void operator=(const Test &t);

此时不能连等赋值,t = t1 = t2;   这个的本质就是:t.operator=(t1.operator=(t2));

所以的有返回值呀,

Test& operator=(const Test &t){
    if(this != &t){
        data = t.data;
    }
    
    return *this;   
}

因为不是创建临时无名对象,所以可以引用返回;临时的不行,返回时空间就已经析构了。

适用场合:Test t;  t = t1 =t2 = t3;(对象已经初始化过了,此时就叫做赋值);

4、函数的优化调用:

#include<iostream>
using namespace std;
class Test{
public:
    Test(int d = 0) : data(d){
        cout<<"Create Test Object"<<this<<endl;
    }
    Test(const Test &t){
        cout<<"Copy Create Test Object"<<this<<endl;
        data = t.data;
    }
    Test& operator=(const Test &t){
        cout<<"Assign : "<<this<<endl;
        if(this != &t){
            data = t.data;
        }
        return *this;
    }
    ~Test(){
        cout<<"Free Test Object"<<endl;
    }
public:
    int GetData()const{
        return data;
    }
private:
    int data;
};
Test fun(Test x){
    int value = x.GetData();
    Test tmp(value);   //创建临时tmp对象,调用构造函数
    return tmp;        //返回值为对象,调用拷贝构造,借助中间桥梁返回;
}                      //立马先析构tmp和x临时对象,在进行赋值语句,最后析构其他对象;  
int main(void){
    Test t1(100);     //创建对象t1,调用构造函数
    Test t2;          //创建对象t2,调用构造函数
    t2 = fun(t1);     //形参,实参传递,调用拷贝构造
    return 0;
}

优化以上的代码,使节省空间和时间:

Test fun(Test &x){
    int value = x.GetData();
    return Test(value);  //创建临时无名对象,编译器直接认为:直接就是这个t2对象
}

int main(void){
    Test t1(100);      //创建对象t1
    Test t2 = fun(t1); //不用再调用赋值语句;

    return 0;
}

效率最低-->代码的优化。

时间: 2024-11-09 19:26:14

引用 拷贝构造 赋值语句的相关文章

为什么类的拷贝构造参数加引用、重载赋值函数的返回值和参数加引用

class string { public: string(const char *str=NULL); string(const string& str);     //copy构造函数的参数为什么是引用呢? string& operator=(const string & str); //赋值函数为什么返回值是引用呢?参数为什么是引用呢? ~string(); }; 下面我就给大家解释一下: class String1 { public: String1(const char*

赋值函数与拷贝构造的差异

C++ 拷贝构造函数 赋值构造函数 ================================= 一句话,赋值函数的前提是对象已定义:而拷贝构造是执行时才会创建一个对象.拷贝构造需要的是深拷贝. 赋值函数一般模式: type& operator =(const type& par) { // (1) 检查自赋值 if( this == &par ) return *this; // (2) 释放原有的内存资源 //(3)分配新的内存资源,并复制内容 ,2.3顺序没讲究,注意释

拷贝构造,深度拷贝,关于delete和default相关的操作,explicit,类赋初值,构造函数和析构函数,成员函数和内联函数,关于内存存储,默认参数,静态函数和普通函数,const函数,友元

 1.拷贝构造 //拷贝构造的规则,有两种方式实现初始化. //1.一个是通过在后面:a(x),b(y)的方式实现初始化. //2.第二种初始化的方式是直接在构造方法里面实现初始化. 案例如下: #include<iostream> //如果声明已经定义,边不会生成 class classA { private: int a; int b; public: //拷贝构造的规则,有两种方式实现初始化 //1.一个是通过在后面:a(x),b(y)的方式实现初始化 //2.第二种初始化的方式是直

【C/C++学院】0819-/类的成员函数与const-mutable /构造与析构/拷贝构造deletedefault以及深浅拷贝/静态成员函数成员变量类在内存的存储默认参数/友元类以及友元函数

类的成员函数与const-mutable 成员函数 Fushu.h #pragma once #include <iostream> class fushu { public: int x; int y; public: fushu(); ~fushu(); void show(); inline void showall(int x, int y);//显式内联 void setxy(int x, int y);//编译器优化,默认隐式内联 void show(int x, int y);

拷贝构造,操作符重载

 拷贝构造 #include <iostream> #include <string.h> using namespace std; class mystring { public: char *s; public: mystring() { s = new char[1024]; cout << "mystring" << endl; } //拷贝构造 mystring(const mystring &it) { s= ne

C++基本函数的调用优化(构造、拷贝构造、赋值)

合理的函数可提升时间和空间的利用率 //Test1.h #include<iostream> using namespace std; struct ST { private: int a; short b; public: ST(int a=0, short b=0):a(a),b(b) { this->a = a; this->b = b; cout<<"Object was Built. "<<this<<endl; }

构造、拷贝构造、赋值、析构

需要注意的问题(当数据成员函数指针型变量,需要申请空间赋值时) 1.构造函数 ①需要给空指针申请一个‘\0’的空间 2.拷贝构造函数 ①传入的参数,必须引用传递否则会出现无休止的拷贝构造 ②对其参数值不做修改,传入的参数需要加const ③避免浅拷贝的产生,每次拷贝构造,都重新申请空间赋值. 3.赋值= ①需要返回引用型变量,否则会再返回值时,创建临时对象,又会无休止的拷贝构造 ②对其参数值不做修改,传入的参数需要加const ③最重要先判断是否是给自己赋值,如果是,直接返回 ④为考虑到异常安全

类的成员函数(构造、析构、拷贝构造、赋值、运算符重载)的实现

以String类为例实现其成员函数 class String { //友元函数重载运算符 friend ostream& operator<<(ostream &out,String& str); friend istream& operator>>(istream& in, String& str); public: //通用构造函数 String(const char* str) { if(!str) //对m_data加NULL

C++之拷贝构造与拷贝赋值

拷贝构造和拷贝赋值------一个有点难的问题 介绍之前,我们需要首先了解深拷贝与浅拷贝的差异: 何为深拷贝,深拷贝不会复制指针,而是令目标对象拥有独立的资源,该资源是从元对象中复制,即先找到对象的指针,在通过指针拷贝其内容: 何为浅拷贝,即之赋值指针的地址,不会赋值指针的目标,容易引发double free异常,即多个目标指向同一个内存: 缺省拷贝构造函数和缺省拷贝赋值函数 如果一个类没有显示的定义一个拷贝构造函数和拷贝赋值运算符,则编译器会为其默认提供一个,但是这个函数只能进行浅拷贝: 如果