1.const与临时对象

一、介绍

  const在C++中代表常量,不光能修饰普通变量,也能修饰指针,还能针对函数的参数、返回值以及类的成员函数进行修饰。

  返回值都具有常性,即临时变量具有有常性。

二、类成员为值形式

class Test
{
public:
    Test(int d = 0) : m_data(d) { }
    ~Test() { }
public:
    //1 返回值,会创建临时变量
    int GetValue() { return m_data; }
    int GetValue() const { return m_data; }

    //2 返回引用,不会创建临时变量
    int& GetRef() { return m_data; }
    int const& GetRef() const { return m_data; } //语法要求返回值加const

    //3 返回地址,会创建临时变量
    int* GetPtr() { return &m_data; }
    int const* GetPtr() const { return &m_data; } //语法要求返回值加const
private:
    int m_data;
};

  1.函数以值形式放回

void Test1()
{
    Test t1(10);
    const Test t2(100);

    int a1 = t1.GetValue();        //OK,将一个临时变量赋值给一个变量
    //int& b1 = t1.GetValue();     //ERROR,临时变量有常性, int const& b1 = t1.GetValue();
    int const& c1 = t1.GetValue(); //OK,用常引用引用一个临时变量

    int a2 = t2.GetValue();        //OK,将一个临时变量赋值给一个变量
    //int& b2 = t2.GetValue();     //ERROR,临时变量具有常性,int const& b2 = t2.GetValue();
    const int& c2 = t2.GetValue(); //OK
}

  2.函数以引用形式返回

void Test2()
{
    Test t1(10);
    const Test t2(100);

    int a1 = t1.GetRef();        //OK,相当于把一个变量赋值给另一个变量
    int& b1 = t1.GetRef();       //OK,引用间的赋值,相当于变量赋值
    const int& c1 = t1.GetRef(); //OK,普通引用赋值给常引用

    int a2 = t2.GetRef();        //OK
    //int& b2 = t2.GetRef();     //ERROR,常方法返回常引用,int const& b2 = t2.GetRef();
    const int& c2 = t2.GetRef(); //OK
}   

  3.函数以地址形式返回  

void Test3()
{
    Test t1(10);
    const Test t2(100);

    int* a1 = t1.GetPtr();          //OK
    //int*& b1 = t1.GetPtr();       //ERROR,临时变量具有常性,int*const& b1 = t1.GetPtr(); 
    //const int*& c1 = t1.GetPtr(); //ERROR,临时变量具有常性,int const*const& c1 = t1.GetPtr(); 

    //int* a2 = t2.GetPtr();        //ERROR,返回值具有常性,int const* a2 = t2.GetPtr();                                     //
    //int*& b2 = t2.GetPtr();       //ERROR,返回值、临时变量具有常性,int const*const& b2 = t2.GetPtr();
    //const int*& c2 = t2.GetPtr(); //ERROR,临时变量具有常性,int const*const& c2 = t2.GetPtr();
}

三、类成员为指针形式

class Test
{
public:
    Test(int d = 0) : m_ptr(new int(d)) { }
    ~Test() { }
public:
    //1返回值,会创建临时变量
    int* GetValue() { return m_ptr; }
    int* GetValue() const { return m_ptr; }

    //2返回引用,不创建临时变量
    int*& GetRef() { return m_ptr; }
    int*const& GetRef() const { return m_ptr; } //语法要求返回值是常引用

    //3返回地址,会创建临时变量
    int** GetPtr() { return &m_ptr; }
    int*const* GetPtr() const{ return &m_ptr; } //语法要求返回值加const
private:
    int* m_ptr;
};

   1.函数以值形式返回

void Test1()
{
    Test t1(10);
    const Test t2(100);

    int* a1 = t1.GetValue();          //OK
    //int* &b1 = t1.GetValue();       //ERROR,临时变量具有常性,int* const& b1 = t1.GetValue();    
    //const int*& c1 = t1.GetValue(); //ERROR,临时变量具有常性,int const*const& c1 = t1.GetValue();

    int* a2 = t2.GetValue();          //OK
    //int*& b2 = t2.GetValue();       //ERROR,临时变量具有常性,int*const& b2 = t2.GetValue();
    //const int*& c2 = t2.GetValue(); //ERROR,临时变量具有常性,int const*const& c2 = t2.GetValue();
}

  2.函数以引用形式返回 

void Test2()
{
    Test t1(10);
    const Test t2(100);
    
    int* a1 = t1.GetRef();          //OK
    int*& b1 = t1.GetRef();         //OK
    //const int*& c1 = t1.GetRef(); //ERROR,int const*const& c1 = t1.GetRef();
    
    int* a2 = t2.GetRef();          //OK
    //int*& b2 = t2.GetRef();       //ERROR,常方法返回的常引用,int*const& b2 = t2.GetRef();
    //const int*& c2 = t2.GetRef(); //ERROR,常方法返回的常引用,int const*const& c2 = t2.GetRef();    
}

  3.函数以地址形式返回

void Test3()
{
    Test t1(10);
    const Test t2(100);

    int** a1 = t1.GetPtr();          //OK
    //int**& b1 = t1.GetPtr();       //ERROR,临时变量具有常性,int**const& b1 = t1.GetPtr();
    //const int**& c1 = t1.GetPtr(); //ERROR,临时变量、返回值具有常性,int*const*const& c1 = t1.GetPtr();
    
    //int** a2 = t2.GetPtr();        //ERROR,返回值具有常性,int*const* a2 = t2.GetPtr();
    //int**& b2 = t2.GetPtr();       //ERROR,临时变量、返回值具有常性,int*const*const& b2 = t2.GetPtr();
    //const int**& c2 = t2.GetPtr(); //ERROR,临时变量、返回值具有常性,int const*const*const& c2 = t2.GetPtr();
}

 四、类成员为对象

class Int
{
public:
    Int(int i = 0) : m_i(i) { }
    Int(Int const& rhs) { m_i = rhs.m_i; }
    ~Int() { }
private:
    int m_i;
};
class Test
{
public:
    Test(int d = 0) : m_data(d) { }
    ~Test() { }
public:
    //1返回对象
    Int GetValue() { return m_data; }
    Int GetValue() const { return m_data; }    
    //2返回引用
    Int& GetRef() { return m_data; }
    Int const& GetRef() const { return m_data; }    
    //3返回地址
    Int* GetPtr() { return &m_data; }
    Int const* GetPtr() const { return &m_data; }
private:
    Int m_data;
};

  1.函数以值形式返回

void Test1()
{
    Test t1(10);
    const Test t2(100);

    Int a1 = t1.GetValue();        //OK,调用默认拷贝构造函数,将匿名对象拷贝给普通对象
    Int& b1 = t1.GetValue();       //OK,调用默认拷贝构造函数,引用匿名对象
    const Int& c1 = t1.GetValue(); //OK,调用默认拷贝构造函数,引用匿名对象

    Int a2 = t2.GetValue();        //OK,调用默认拷贝构造函数,将匿名对象拷贝给普通对象
    Int& b2 = t2.GetValue();       //OK,调用默认拷贝构造函数,引用匿名对象
    const Int& c2 = t2.GetValue(); //OK,调用默认拷贝构造函数,引用匿名对象
}

  2.函数以引用形式返回

void Test2()
{
    Test t1(10);
    const Test t2(100);

    Int a1 = t1.GetRef();        //OK
    Int& b1 = t1.GetRef();       //OK
    const Int& c1 = t1.GetRef(); //OK

    Int a2 = t2.GetRef();        //OK 
    //Int& b2 = t2.GetRef();     //ERROR,常方法返回常引用,Int const& b2 = t2.GetRef();
    const Int& c2 = t2.GetRef(); //OK
}

  3.函数以地址形式返回

void Test3()
{
    Test t1(10);
    const Test t2(100);

    Int* a1 = t1.GetPtr();          //OK
    //Int*& b1 = t1.GetPtr();       //ERROR,临时变量具有常性,Int*const& b1 = t1.GetPtr();
    //const Int*& c1 = t1.GetPtr(); //ERROR,临时变量具有常性,Int const*const& c1 = t1.GetPtr();
    
    //Int* a2 = t2.GetPtr();        //ERROR,临时变量具有常性,Int const* a2 = t2.GetPtr();    
    //Int*& b2 = t2.GetPtr();       //ERROR,临时变量、返回值具有常性,Int const*const& b2 = t2.GetPtr();
    //const Int*& c2 = t2.GetPtr(); //ERROR,临时变量具有常性,Int const* const& c2 = t2.GetPtr();
}
原文地址:https://www.cnblogs.com/csqtech/p/5759336.html