一、介绍
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(); }