1. 程式人生 > 其它 >C++的this指標和引用符號的搭配使用理解

C++的this指標和引用符號的搭配使用理解

技術標籤:C++核心程式設計c++

看到一個C++視訊教程裡關於this指標講解的時候多次用到了引用,老師的程式碼如下:

class Person {
public:
    Person(int age)
    {
        this -> age = age;
    }

    Person& PersonAddAge(Person &p)
    {
        this->age += p.age; //把別人的age加到自己上面

        //this指向p2的指標,而*this指向的是p2這個物件的本體
        return *this;
    }
    int age;
};

void test01()
{
    Person p1(10);
    Person p2(10);

    p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1);
    cout<<"p2的年齡為:"<<p2.age<<endl;
}

int main() {

    test01();

	system("pause");

	return 0;
}

其執行結果為:p2的年齡為:40

我關注的是其中的下面這行程式碼裡為什麼需要這兩個引用符號,因為*this已經可以表示指向原物件了,那為啥要多次一舉呢?

首先第二個引用符號在這裡是不需要的(老師的附屬檔案裡也沒有第二個引用符號,可能講的時候沒注意),放在這裡不算錯只是引用的作用是讓被引用變數的值一起改變,而我們這裡被引用變數的值是用來加到前面的,沒有改變其值,所以這個引用符號可以去掉。

那第一個引用符號又是為何呢?為了說明清楚,我們將增加幾行程式碼,讓諸位更加看清this的本質(去掉了引用符號,且每次輸出age值)

class Person {
public:
    Person(int age)
    {
        this -> age = age;
    }

    Person PersonAddAge(Person p)
    {
        this->age += p.age; //把別人的age加到自己上面

        //this指向p2的指標,而*this指向的是p2這個物件的本體
        cout<< (*this).age<<endl;//
        return *this;
    }
    int age;
};

void test01()
{
    Person p1(10);
    Person p2(10);

    cout<<p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1).age<<endl;//
    cout<<"p2的年齡為:"<<p2.age<<endl;
}

int main() {

    test01();

	system("pause");

	return 0;
}

發現不加引用符號,雖然最終結果是40,但是p2的age值只是加了一次,即相當於三次呼叫函式中只有第一次指向的是原物件p2,其原因是不加引用符號,那麼return的結果只是將*this指向的物件複製給一個臨時物件,而不是真正的原物件。就好比普通函式中return x,返回的只是x的複製的值。即這裡只有第一次函式內部對原物件p2進行了修改,而後面每次呼叫都是對臨時物件操作的。那麼如果加上引用符號&之後,就使得每次的臨時物件是原物件p2的一個別名,即每次呼叫函式都改變了原物件p2內的引數。

這才有了老師附的如下完整程式碼:

class Person
{
public:

	Person(int age)
	{
		//1、當形參和成員變數同名時,可用this指標來區分
		this->age = age;//this指標指向被呼叫的成員函式所屬的物件。
	}

	Person& PersonAddPerson(Person p)
	{
		this->age += p.age;
		//返回物件本身
		return *this;
	}

	int age;
};

void test01()
{
	Person p1(10);
	cout << "p1.age = " << p1.age << endl;

	Person p2(10);
	p2.PersonAddPerson(p1).PersonAddPerson(p1).PersonAddPerson(p1);
	cout << "p2.age = " << p2.age << endl;
}

int main() {

	test01();

	system("pause");

	return 0;
}

自結:要加引用符號return的才是真正的P2物件本身,否則只是P2的一個copy。即如果沒有&,那麼後面操作就不會改變P2了

補充:原來老師視訊的最後講了這個哈哈哈哈,我看到一半的時候因為老師直接加了&導致我不理解就自己摸索原理去了,同時寫了上面的文章,寫完了繼續看視訊的時候發現老師有講,原因是:以值的方式返回區域性物件會呼叫拷貝建構函式,從而生成新的匿名變數。和我上面理解的差不多,也就是不加引用的話是p2`,p2``……,總之p2的屬性值就不會變了。

其實一句話要想實現這種鏈式程式設計,記住加&就行了。