首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

深入理解 C++ 構造函數中的 this 指針:能用、不能用與最佳實踐

     編輯:關於C++

核心原理

有人認為構造函數中不應使用 this 指針,因為對象「尚未完全形成」。實則不然,只要謹慎,在函數體與初始化列表中均可安全使用 this。因為「未完全形成」不等於「什麼都沒有」。

進入構造函數(及其鏈式調用)前,編譯器已完成:

  • 為類實例分配內存
  • 建立運行時所需信息(如虛函數表 vtbl)
  • 缺省構造所有類成員
構造前準備

【能】可靠訪問的成員

構造函數體(或其調用的函數)能 可靠訪問:

  • 基類中聲明的數據成員
  • 當前類聲明的數據成員

原因:這些成員在構造函數體開始執行時已完整建立。

【不能】向下調用被派生類重寫的虛函數

構造函數體(或其調用的函數)不能 向下調用被派生類重定義的虛函數。因為在基類構造期間,「對象還不是一個派生類對象」。

【有時】視情況可行的操作

  • 將 this 的某數據成員傳給另一數據成員的初始化程序: 必須確保該成員已初始化。需掌握語言規則:基類子對象優先初始化(多重/虛繼承順序較複雜),然後按類中聲明順序初始化成員。若不確定規則,切勿在初始化列表中傳遞任何成員(無論是否顯式用 this)。

實際用途:小對象協作的配置時機

優秀的 OO 設計強調「高內聚」,產生許多單一職責的小對象。小對象間的協作需配置(如 Observer 模式中 subject.RegisterObserver(observer),DirectShow 中 filterGraph.SetVideoWindow(videoWindow))。構造函數正是典型的配置時機:

class CMyWindow : public CWnd {
private:
    CFilterGraph filterGraph;
public:
    CMyWindow() { filterGraph.SetVideoWindow(this); } // 此處安全使用 this
};

附錄:基礎知識總結表

表一:誰被調用普通函數構造函數析構函數
調用順序class::fun()superclass::superclass() → subclass::subclass()subclass::~subclass() → superclass::~superclass()

表二:虛函數在哪裡被調用非虛函數虛函數
普通函數class::fun()obj.vfun()
構造函數class::fun()class::vfun() (靜態綁定)
析構函數class::fun()class::vfun() (靜態綁定)

關鍵認知: 「構造/析構/普通」與「虛/非虛」是完全獨立的分類維度:

  • 只要是「構造/析構」就「串聯調用」
  • 只要是「虛函數」就「可能 obj.vfun()」
  • 它們「一起生效」但「不互相干擾」

虛析構函數示例:

class superclass { virtual ~superclass() { println("superclass::~superclass()") }; };
class subclass : public superclass { virtual ~subclass() { println("subclass::~subclass()") }; };

superclass* super = new subclass();
delete super; // 輸出:subclass::~subclass() → superclass::~superclass()

執行 delete super 時:是串聯調用(因是析構函數),從 subclass::~subclass() 開始(因實際對象類型是 subclass)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved