久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

在模板派生類中,為什么我需要使用“this->&

In a templated derived class, why do I need to qualify base class member names with quot;this-gt;quot; inside a member function?(在模板派生類中,為什么我需要使用“this-來限定基類成員名稱?在成員函數中?) - IT屋
本文介紹了在模板派生類中,為什么我需要使用“this->"來限定基類成員名稱?在成員函數中?的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

當我調查 Qt 的源代碼時,我看到 trolltech 人員明確使用 this 關鍵字來訪問析構函數上的字段.

While I investigate source code of Qt I saw that trolltech guys explicitly use this keyword to access a field on destructor.

inline ~QScopedPointer()
{
    T *oldD = this->d;
    Cleanup::cleanup(oldD);
    this->d = 0;
}

那么,這種用法有什么意義呢?有什么好處嗎?

So, what's the point of this usage? Are there any benefits?

對于那些投票結束這個問題的人,我懷疑這種用法是用于某些類繼承的情況

For those who vote for closing this question, I suspect that this usage is for some class inheritance cases

QScopedPointer 類定義的一部分:

template <typename T, typename Cleanup = QScopedPointerDeleter<T> >
class QScopedPointer

推薦答案

C++ 答案(一般答案)

考慮一個帶有模板基類的模板類Derived:

template <typename T>
class Base {
public:
    int d;
};

template <typename T>
class Derived : public Base<T> {
    void f () {
        this->d = 0;
    }
};

this 具有類型 Derived,該類型依賴于 T.所以 this 有一個依賴類型.所以 this->d 使 d 成為依賴名稱.依賴名稱在模板定義的上下文中作為非依賴名稱和實例化上下文進行查找.

this has type Derived<T>, a type which depends on T. So this has a dependent type. So this->d makes d a dependent name. Dependent names are looked-up in the context of the template definition as non-dependent names and in the context of instantiation.

如果沒有 this->,名稱 d 只會作為非依賴名稱被查找,而不會被找到.

Without this->, the name d would only be looked-up as a non-dependent name, and not be found.

另一種解決方案是在模板定義本身中聲明d:

Another solution is to declare d in the template definition itself:

template <typename T>
class Derived : public Base<T> {
    using Base::d;
    void f () {
        d = 0;
    }
};

Qanswer(具體答案)

d 是 成員QScopedPointer.它不是繼承的成員.this-> 在這里不是必需的.

Qanswer (specific answer)

d is a member of QScopedPointer. It isn't an inherited member. this-> is not necessary here.

OTOH,QScopedArrayPointer 是一個模板類,d 是一個模板基類的繼承成員:

OTOH, QScopedArrayPointer is a template class and d is an inherited member of a template base class:

template <typename T, typename Cleanup = QScopedPointerArrayDeleter<T> >
class QScopedArrayPointer : public QScopedPointer<T, Cleanup>

所以 this-> 是必要的 此處:

inline T &operator[](int i)
{
    return this->d[i];
}

很容易看出,將 this-> 放在任何地方更容易.

It's easy to see that it's easier to just put this-> everywhere.

我想所有 C++ 用戶都不清楚為什么在非依賴基類中查找名稱而不是在依賴基類中查找名稱:

I guess it isn't clear to all C++ users why names are looked-up in non-dependent base classes but not in dependent base classes:

class Base0 {
public:
    int nd;
};

template <typename T>
class Derived2 : 
        public Base0, // non-dependent base
        public Base<T> { // dependent base
    void f () {
        nd; // Base0::b
        d; // lookup of "d" finds nothing

        f (this); // lookup of "f" finds nothing
                  // will find "f" later
    }
};

除了標準這么說"之外還有一個原因:模板中名稱綁定的工作方式.

There is a reason beside "the standard says so": cause of way name binding in templates works.

模板可以具有后期綁定的名稱,當模板被實例化時:例如 f (this) 中的 f.在Derived2::f() 定義點,編譯器不知道變量、函數或類型名稱f.f 可以引用的一組已知實體此時是空的.這不是問題,因為編譯器知道它稍后會查找 f 作為函數名或模板函數名.

Templates can have name that are bound late, when the template is instantiated: for example f in f (this). At the point of Derived2::f() definition, there is no variable, function or type name f known by the compiler. The set of known entities that f could refer to is empty at this point. This isn't a problem because the compiler knows it will lookup f later as a function name, or a template function name.

OTOH,編譯器不知道如何處理d;它不是(被調用的)函數名.無法對非(被調用)函數名稱進行后期綁定.

OTOH, the compiler doesn't know what to do with d; it isn't a (called) function name. There is no way to do late binding on non-(called) functions names.

現在,所有這些看起來像是編譯時模板多態的基本知識.真正的問題似乎是:為什么在模板定義時 d 沒有綁定到 Base::d?

Now, all of this may seem like elementary knowledge of compile-time template polymorphism. The real question seems to be: why isn't d bound to Base<T>::d at template definition time?

真正的問題是在模板定義時沒有Base::d,因為沒有完整的類型Base那個時候:Base 被聲明了,但沒有定義! 你可能會問:那怎么辦:

The real issue is that there is no Base<T>::d at template definition time, because there is no complete type Base<T> at that time: Base<T> is declared, but not defined! You may ask: what about this:

template <typename T>
class Base {
public:
    int d;
};

看起來像是一個完整類型的定義!

it looks like the definition of a complete type!

實際上,直到實例化,它看起來更像是:

Actually, until instantiation, it looks more like:

template <typename T>
class Base;

編譯器.不能在類模板中查找名稱!但僅限于模板特化(實例化).模板是使模板特化的工廠,模板不是模板特化的集合.編譯器可以在 Base 中查找任何特定類型的 T 中的 d,但它不能在類模板Base 中查找d.在確定類型 T 之前,Base::d 仍然是抽象的 Base::d;只有當類型 T 已知時,Base::d 才開始引用 int 類型的變量.

to the compiler. A name cannot be looked-up in a class template! But only in a template specialisation (instantiation). The template is a factory to make template specialisation, a template isn't a set of template specialisation. The compiler can lookup d in Base<T> for any particular type T, but it cannot lookup d in the class template Base. Until a type T is determined, Base<T>::d remains the abstract Base<T>::d; only when type T is known, Base<T>::d start to refer to a variable of type int.

這樣做的結果是類模板 Derived2 有一個完整的基類 Base0 但是一個不完整的(前向聲明的)基類 <代碼>基礎.僅對于已知類型 T,模板類"(類模板的特化)Derived2 具有完整的基類,就像任何普通類一樣.

The consequence of this is that the class template Derived2 has a complete base class Base0 but an incomplete (forward declared) base class Base. Only for a known type T, the "template class" (specialisations of a class template) Derived2<T> has a complete base classes, just like any normal class.

你現在看到了:

template <typename T>
class Derived : public Base<T> 

實際上是一個基類規范模板(一個制作基類規范的工廠),它遵循與模板內的基類規范不同的規則.

is actually a base class specification template (a factory to make base class specifications) that follows different rules from a base class specification inside a template.

備注:讀者可能已經注意到,我在解釋的最后編了幾句.

Remark: The reader may have noticed that I have made-up a few phrases at the end of the explanation.

這是非常不同的:這里dDerived中的限定名,而Derived是依賴的,因為T 是一個模板參數.限定名稱可以是后期綁定的,即使它不是(被調用的)函數名稱.

This is very different: here d is a qualified name in Derived<T>, and Derived<T> is dependent since T is a template parameter. A qualified name can be late-bound even if it isn't a (called) function name.

另一種解決方案是:

template <typename T>
class Derived : public Base<T> {
    void f () {
        Derived::d = 0; // qualified name
    }
};

這是等價的.

如果您認為在 Derived 的定義中,將 Derived 視為已知的完整類,有時將其視為未知類有時不一致,嗯,你是對的.

If you think that inside the definition of Derived<T>, the treatment of Derived<T> as a known complete class sometimes and as an unknown class some other times in inconsistent, well, you are right.

這篇關于在模板派生類中,為什么我需要使用“this->"來限定基類成員名稱?在成員函數中?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

相關文檔推薦

How can I read and manipulate CSV file data in C++?(如何在 C++ 中讀取和操作 CSV 文件數據?)
In C++ why can#39;t I write a for() loop like this: for( int i = 1, double i2 = 0; (在 C++ 中,為什么我不能像這樣編寫 for() 循環: for( int i = 1, double i2 = 0;)
How does OpenMP handle nested loops?(OpenMP 如何處理嵌套循環?)
Reusing thread in loop c++(在循環 C++ 中重用線程)
Precise thread sleep needed. Max 1ms error(需要精確的線程睡眠.最大 1ms 誤差)
Is there ever a need for a quot;do {...} while ( )quot; loop?(是否需要“do {...} while ()?環形?)
主站蜘蛛池模板: 求个av网址 | 亚洲视频在线一区 | 国产精品s色 | 日韩在线免费 | 国产精品久久久久久久久 | jlzzjlzz国产精品久久 | 成年人黄色免费视频 | 久久久久国产一区二区三区四区 | 亚洲一二三区精品 | 天天干天天草 | 欧美一级高潮片免费的 | 成人在线免费 | 国产成人免费视频网站高清观看视频 | 国产精品久久久 | 国产日韩精品在线 | 亚洲成人久久久 | 久久久久久久久久久久久久国产 | 欧美一级二级在线观看 | 久久久精品一区二区三区 | 欧美亚洲综合久久 | 婷婷综合| 五月激情六月婷婷 | av看片| 一二三四在线视频观看社区 | 亚洲午夜精品一区二区三区他趣 | 欧美不卡一区二区三区 | 91一区二区| 欧洲一级毛片 | 久久www免费视频 | 欧美一区日韩一区 | 国产精品久久久久久久毛片 | 亚洲伊人久久综合 | 日韩一二三区视频 | 久草久草久草 | 粉嫩一区二区三区国产精品 | 91久久国产精品 | 亚洲高清在线 | 精品国产乱码久久久久久影片 | 亚洲国产一区二区三区, | 日日操网站 | 久久国产亚洲精品 |