繁体   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