簡體   English   中英

如何在C ++中實現元類?

[英]How can I implement metaclasses in C++?

我一直在讀一些關於元類的內容,但我想知道它們是否可以用C ++實現。

我知道Qt庫正在使用MetaObjects,但它使用C ++的擴展來實現它。 我想知道它是否可以直接在C ++中使用。

謝謝。

Gamma等人的“設計模式”一書中的一些模式具有與元類概念類似的特征。 例如,“策略”模式允許您在創建時自定義對象行為。 信封成語是另一個緊密的匹配。 但是,不要讓你自定義類的接口。

在COM中,IDispatch接口允許在運行時動態地向對象添加方法/屬性。 但這意味着放棄標准的c ++方法調用。 每個調用都通過相同的方法,它將索引或字符串鍵轉換為用戶維護的方法/屬性表,並且所有參數必須作為對象數組傳遞。

使用這兩種技術可以獲得元類的靈活性,但由於沒有語法優點或運行時/編譯器幫助,這是一個更難的問題。

戴夫

如果元類的工作定義是“實例化本身就是類的語言實體”,那么泛型就是C ++中的元類:

#include <iostream>
using namespace std;

template <typename T>
class Meta {
public:
    Meta(const T&init) : mData(init) {}
// ...
private:
    T mData;

};

int main(int, char **) {
  cout << "The size of Meta<double> is " << sizeof(Meta<double>) << endl ;
  return 0;
}

在倒數第三行中使用Meta <double>迫使編譯器實例化Meta <double>類; sizeof運算符對Meta進行操作,從而證明這不僅僅是語義糖,而且已經實例化了類。 即使沒有實例化Meta類型的對象,該程序也是完整的。

C ++沒有內置的元類支持(不是Python / Objective-C方式),但是你可以手動模仿元類的行為。 基礎非常簡單,您可以創建一個具有更長壽命的額外類(Singleton,靜態對象或First First Use Idiom ),它能夠創建和操作它的相應類。 (在Objective-C中,元類通常包含'靜態'成員變量,內存分配/釋放例程等等)。

Qt所做的是,他們采用了元類的概念並對其進行了修改,以便它們可以支持某種形式的反射(以及不支持它的系統上的RTTI)。 實現這一點需要大量的宏魔法或自定義編譯器(例如他們選擇使用)。

但一般來說,常規元類提供的大多數功能都已由C ++語言提供; 只是以不同的形式。 實際上,您想要元對象的唯一原因是出於反射的目的,有很多方法可以在C ++中實現反射,如本文檔所述

除此之外,如果您真的設置在Objective-C風格的元類系統上,我不知道有任何庫可以做到這一點,但可能很有。 另一方面,滾動自己也不應該那么困難。

您可以查看此博客文章。

https://herbsutter.com/2017/07/26/metaclasses-thoughts-on-generative-c/

Meta類可能會進入C ++,但還需要一段時間。

不敢......至少不是原生的。

擁有元類通常需要存在表示類的運行時對象,如Java中的情況。

在C ++中,類沒有運行時表示。 它們的表現形式出現在虛擬表中。 但在許多方面,它們像C函數一樣運行,所有OOP幾乎都作為粘合代碼運行。

話雖這么說,你可能希望用其他語言的元類實現很多東西的OOP模式。 您還可以“模擬”自己的對象系統。

可以創建元類,但是C ++並不是這樣,它是基於靜態編譯時的實現,而不是運行時靈活性。

無論如何,它取決於你是想要帶有方法的元類還是帶有數據的元類,數據類可以使用像boost :: any這樣的Boost構造來實現,如果你想要帶有方法的類,你可以使用boost :: bind來將方法綁定到對象,或者您可以使用COM-objects之類的單入口點接口自行實現它們。

然而,“真正的”C ++方式是使用泛型,因此它可以在編譯時確定,以獲得最佳性能。

說實話,我見過很少的系統,雖然我已經看到了一些,真正需要運行時的靈活性,在大多數情況下,對象誕生並死於同一個類,或者至少足以將其生命周期的95%用作單個系統他們一出門就上課。

因此,在許多情況下,人們發現自己為運行時元類付出了太多。 當然,有一種觀點認為這可以提供更好的開發人員性能,但在許多情況下,每行代碼將在硬件上運行比寫入代碼所花費的時間多幾億倍。 因此,您可以將編譯時和運行時類視為前期支付或租賃。 我個人喜歡預付。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM