【发布时间】:2020-11-20 00:04:18
【问题描述】:
所以,伙计们,我有一个抽象类,另一个类将这个类的实现存储在堆栈中(我不想要堆分配,而且我不知道在不让调用者明确声明的情况下其他方法实现)和另一个存储此接口类的引用。但是,GCC似乎没有将实现类存储在堆栈中,并且在使用接口类时可能找不到实现类vtable。
基本上,在没有优化的情况下使用 GCC 4.8.1 编译时一切正常,但是当我尝试使用它时,程序崩溃然后返回 139。
我不知道为什么 GCC 4 不支持它,而 GCC 5 支持,但我看到它们会生成不同的指令。
编译器资源管理器:https://godbolt.org/z/Wfvj65
#include <cstdio>
#define FORCEINLINE inline __attribute__((always_inline))
class IFormatter
{
public:
virtual void Format(const void* InData) const = 0;
};
template<typename T>
class TFormatter :
public IFormatter
{
public:
TFormatter() = delete;
};
using Scalar = float;
// Implemented, fine.
struct RVector2
{
Scalar X;
Scalar Y;
};
// Not implemented, get error.
struct RVector3
{
Scalar X;
Scalar Y;
Scalar Z;
};
template<>
class TFormatter<RVector2> :
public IFormatter
{
public:
virtual void Format(const void*) const override
{
printf("[RVector2]\n");
}
};
template<typename T>
class TCustom
{
public:
FORCEINLINE TCustom(const T& InValue) :
Value(InValue),
Format(TFormatter<T>{})
{
}
FORCEINLINE const T* Data() const
{
return &Value;
}
FORCEINLINE const IFormatter& Formatter() const
{
return Format;
}
private:
const T& Value;
TFormatter<T> Format;
};
template<typename T>
FORCEINLINE TCustom<T> MakeCustom(const T& InValue)
{
return TCustom<T>{ InValue };
}
class RCustom
{
public:
FORCEINLINE RCustom(const void* InValue, const IFormatter& InFormatter) :
Data(InValue),
Formatter(InFormatter)
{
}
template<typename T>
FORCEINLINE RCustom(TCustom<T> const& InCustom) :
RCustom(InCustom.Data(), InCustom.Formatter())
{
}
FORCEINLINE const IFormatter& Get() const
{
return Formatter;
}
private:
const void* Data;
const IFormatter& Formatter;
};
int main()
{
const RVector2 Vector{};
const RCustom Custom = MakeCustom(Vector);
Custom.Get().Format(nullptr);
return 0;
}
【问题讨论】:
-
一个对象对其成员的存储位置没有影响,这在对象的创建者手中。
-
我可能遗漏了一些东西 - 但这应该如何工作?您创建一个
TCustom<RVector2>对象并将结果存储在一个看似无关的类型RCustom?注意RCustom和TCustom之间的差异——一个通过引用存储IFormatter,另一个通过值存储TFormatter。如果从RCustom中删除&,则代码有效。
标签: c++ c++11 gcc visual-c++ abstract-class