非多态继承是否有 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
我很好奇继承在 非多态 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