非多态继承是否有 performance/memory 使用影响?

Is there a performance/memory usage impact in non-polymorphic inheritance?

我很好奇继承在 非多态 class 中的影响。具体来说,我正在编写两个智能指针 classes, 都没有使用虚拟方法 ,并且都用于非常独特的目的。由于基本运算符重载和一些标准函数是相同的,而且它们只需要一个成员变量,所以我想我可以使用基数 class 来重用代码。这是我的意思的简单 模型

基地class:

template <class T>
class Pointer_Impl
{
public:
    T & operator*() { return this->*m_pointer; }
    // etc.
protected:
    T *m_pointer;
    //protected to prevent instantiation without using = delete
    Pointer_Impl() {}
    Pointer_Impl(T *) {}
    //other constructors, assignment and move operators, destructor here
};

然后:

template <class T>
class PointerA : public Pointer_Impl<T>
{
public:
    PointerA() { m_pointer = nullptr; }
    PointerA(T * obj) { m_pointer = obj; }
    // other constructors, assignment and move operators, destructor, and any other class-specific functions here
};

问题:从缺少任何虚拟方法的基 class 派生时,是否会在内存或性能方面产生任何开销?由于它是一个智能指针实现,因此精益求精是我要找的。

我的直觉告诉我没有,不用担心,但我想从更聪明的头脑中确定。

你的子class的构造函数表明子class包含至少一个你没有显示的额外成员m_object

如果没有任何虚方法,在运行时,由 superclass 和 subclass 组成的对象与由单个 class 组成的对象没有区别,与典型的 C++ 实现。毕竟,创建一个子 class 最终会创建一个新的 class。因此,包含基 class 和子 class 的所有成员的单个 class 在运行时与单个 class 无法区分,只要所有 class成员相同,排列顺序相同,不涉及虚拟继承。

当然,编译器必须做更多的工作来跟踪 superclass 和 subclass,所以编译器可能需要做一些额外的工作必须做,跟踪两个单独的 classes,而不是一个。但是除非代码库很大,否则我怀疑根本无法衡量性能差异。

性能影响

None。如果没有 virtual(虚拟继承或虚拟函数),您将不会因使用基 class 而招致任何运行时惩罚。名称解析完全在编译时使用静态类型执行。

内存影响

None。在没有 virtual 的情况下,继承的 class 与直接作为成员具有相同字段的 class 之间没有任何有意义的区别。如果你有多个基础 classes 或 virtual(继承或函数),这一切都会改变。

编译影响

编译时间可能会有些影响;编译器将不得不跟踪更多的名称和模板实例化。这是有时 大型模板代码库的一个问题。

没有 运行 任何类型的时间性能损失(如果优化的话。显然调试版本可能会存储一些关于继承的数据)。

作为证据,观察以下程序的输出

程序 1:

template <class T>
class PointerA
{
public:
    PointerA(T * obj) : m_pointer(obj) {}
    T & operator*() { return *this->m_pointer; }
    T *m_pointer;
};

prog2:

template <class T>
class Pointer_Impl
{
public:
    T & operator*() { return *this->m_pointer; }
protected:
    T *m_pointer;
    Pointer_Impl(T *) {}
};

template <class T>
class PointerA : public Pointer_Impl<T>
{
public:
    PointerA(T * obj) : Pointer_Impl<T>(obj) {}
};

共同的主线:

int main() {
    PointerA<int> p(new int);
    volatile int i = 42;
    *p = i;
    i = *p;
}

两者生成相同的程序集:

main:
        subq    , %rsp
        movl    , %edi
        call    operator new(unsigned long)
        movl    , 12(%rsp)
        movl    12(%rsp), %eax
        movl    %eax, 12(%rsp)
        movl    [=13=], %eax
        addq    , %rsp
        ret