zoukankan      html  css  js  c++  java
  • c++ 常成员函数 和 常对象

    版权声明:本文为博主原创文章。未经博主同意不得转载。 https://blog.csdn.net/zhuyingqingfen/article/details/31751111

    先明白几个概念:

    1. 常对象仅仅能调用常成员函数。

    2. 普通对象能够调用所有成员函数。

    3. 当对一个对象调用成员函数时,编译程序先将对象的地址赋给this指针,然后调用成员函数。每次成员函数存取数据成员时,由隐含使用this指针。
    4. 当一个成员函数被调用时,自己主动向它传递一个隐含的參数。该參数是一个指向这个成员函数所在的对象的指针。
    5. 在C++中,this指针被隐含地声明为: X *const this,这意味着不能给this 指针赋值。
       在X类的const成员函数中,this指针的类型为:const X* const, 这说明this指针所指向的这样的对象是不可改动的(即不能对这样的对象的数据成员进行赋值操作);
    6. 由于this并非一个常规变量。所以。不能取得this的地址。

    如:

      

    #include <iostream>
    
    class A
    {
    public:
    	A():mValue(0)
    	{
    
    	}
    	void print() 
    	{
    		std::cout<<"hello";
    	}
    	int GetValue()
    	{
    		return mValue;
    	}
    	int GetValue()const
    	{
    		return mValue;
    	}
    
    private:
    	int mValue;
    };
    
    void test(A & const a)
    {
    
    }
    
    int main()
    {
    	
    	const A a;//const A* const this ;	
    	a.print(); //错误。将会提示 error C2662: “A::print”: 不能将“this”指针从“const A”转换为“A &”
    
    	test(a); //error C2664: “test”: 不能将參数 1 从“const A”转换为“A &”
    }


    由于a是const对象。所以a仅仅能调用类A中的常成员函数。


    那么为什么会提示:“不能将this指针.......”的语句呢?

    由于对于c++的成员函数(当然不是静态成员函数),都会含有一个隐藏的參数,对于上例A中的int GetValue()函数,在编译后会变成:

    int GetValue(A * const this);  //不能改动this变量,但能够改动this指向的内容。即:this是常量指针。

    而对于int GetValue()const ,编译后是:

    int GetValue(const A* const this); 

    仅仅所以this指针是const类型,由于在某次调用整个过程this指向都不同意改变(原因非常easy。假设改变的话就不是这个对象调用的了)

    从编译后的结果看就非常清楚了。 由于a是const,所以其this指针就相应: const A* const this ;

    而print函数被编译出来后相应的是void print(A* const this); 在进行參数匹配时, 所以就会提示 “不能将“this”指针从“const A ....."


    this指针的出现就解释了。所有类A的对象都是公用一套代码模版,为什么各个对象在调用成员函数的时候不会乱套。


    原来C++为成员函数提供了一个名字为this的指针。这个指针称为自引用指针。

    每当创建一个对象时,系统就把this指针初始化为指向该对象。每当调用一个成员函数时。系统就自己主动把this指针作为一个隐含的參数传给该函数。不同的对象调用同一个成员函数时,C++编译器将依据成员函数this指针所指向的对象来确定应该引用哪一个对象的数据成员。通常情况下。this指针是隐含存在的。也能够将其显示的表示出来(即如上例中的 this->mValue。

    只是this指针仅仅能在类中使用)



    还有就是  this指针是一个const指针。不能再程序中改动它或给它赋值;



  • 相关阅读:
    二、网络基础
    Ado.net
    LINQ
    C#[抽象类,接口]
    自定义类库,并引用
    c#重点[封装,继承,多肽]
    c#重点[集合类型]异常,数组,集合ArrayList,List<>,hashTable,hashtable泛型(Dictionary)
    c#重点[数据类型,构造方法,变量,变量,运算符,装箱,拆箱]
    .net reflector激活
    sqlsever备份,还原和导入导出方法
  • 原文地址:https://www.cnblogs.com/mqxnongmin/p/10499403.html
Copyright © 2011-2022 走看看