簡體   English   中英

使用 CRTP 時確保安全

[英]Ensure safety while using CRTP

考慮以下使用 CRTP 的代碼片段

#include <iostream>

struct Alone
{
    Alone() { std::cout << "Alone constructor called" << std::endl; }
    int me {10};
};

struct Dependant
{
    explicit Dependant(const Alone& alone)
        : ref_alone(alone)
    { std::cout << "Dependant called with alone's me = " << alone.me << std::endl; }
    const Alone& ref_alone;
    void print() { std::cout << ref_alone.me << std::endl; }
};

template <typename D>
struct Base
{
    Base() { std::cout << "Base constructor called" << std::endl; }

    D* getDerived() { return static_cast<D*>(this); }
    Dependant f { getDerived()->alone };
    void print() { f.print(); }
};

struct Derived : Base <Derived>
{
    Derived() { std::cout << "Derived constructor called "  << std::endl; }
    Alone alone {};
    void print() { Base::print(); };
};

int main()
{
    Derived d;
    d.print();
}

原文鏈接http://coliru.stacked-crooked.com/a/79f8ba2d9c38b965

我首先有一個基本問題

  • 使用繼承時內存分配如何發生? 我知道構造函數是從 Base 調用到 Derived 的,但似乎當我這樣做時

    派生 d;

    分配相當於sizeof(D) 的內存,然后調用構造函數。 我的理解在這里正確嗎? (這將解釋打印未初始化的成員)

  • 考慮到上述示例,您會建議/推薦有關 CRTP 的任何最佳實踐嗎?

分配相當於 sizeof(D) 的內存,然后調用構造函數

否則它怎么可能工作? 您不能在尚未分配的內存中構造對象。 內存分配總是在對象構造之前進行。

考慮到上述示例,您會建議/推薦有關 CRTP 的任何最佳實踐嗎?

CRTP 的標准做法:不要在構造函數/析構函數中調用 CRTP。 虛函數也是如此。 Virtuals 是動態多態性,而 CRTP 是靜態多態性。 但是它們都使用相同的基本機制:一個定義派生類必須實現的接口的基類。

就像使用虛函數一樣,嘗試在構造函數/析構函數中調用它不會達到您的意思。 唯一的區別是對於虛函數,編譯器實際上會阻止您獲得未定義的行為。 而使用 CRTP,您只會損壞。

請注意,這包括默認成員初始化程序,出於非聚合的目的,它們只是構造函數初始化列表的簡寫。

暫無
暫無

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

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