覆盖不明确的继承
override ambiguous inheritence
我正在努力提供一组需要结构感知的序列化方法。因此,我构建了一个 class 模板,为所有从它继承的 class 提供这些方法。
这是我现在拥有的:
template<typename T>
class serializable
{
protected:
serializable() = default;
public:
size_t size_of() { return sizeof(T); }
void dump(void* data) { std::memcpy(data, this, serializable<T>::size_of()); }
void load(void* data) { std::memcpy(this, data, serializable<T>::size_of()); }
virtual void serialize()
{
std::cout << "Default serialize : size " << serializable<T>::size_of() << std::endl;
}
};
struct point : public serializable<point>
{
float p[3];
};
struct particle : public point, public serializable<particle>
{
float v[3];
};
int main()
{
particle p;
p.serialize();
return 0;
}
问题是在调用 p.serialize
时,编译器在 serializable<point>::serialize()
和 serializable<particle>::serialize()
之间发出不明确的重载错误。
我该如何解决这个问题?有什么方法可以覆盖 serializable<point>
的继承,只考虑 serializable<particle>
?我应该考虑另一种方法吗?
你可以把你想要的 serialize
带进来:
struct particle : public point, public serializable<particle>
{
using serializable<particle>::serialize;
float v[3];
};
但您可能只想使用组合:
struct particle : public serializable<particle>
{
point p;
float v[3];
};
How can I solve this ?
覆盖 particle
中的 serialize()
。无论如何,您都需要序列化点数据和粒子自己的数据。基础 class 的 serialize
的默认实现将无法为 particle
.
做正确的事情
出于同样的原因,您还需要覆盖 point
中的 serialize()
。
此外,我认为将 point
作为 particle
的基础 class 似乎不正确。 particle
不是 point
。它有一个位置和速度。聚合对我来说似乎是更好的方法。
struct point : public serializable<point>
{
void serialize()
{
// Serialize p
// ...
}
float p[3];
};
struct particle : public serializable<particle>
{
void serialize()
{
// Serialize location.
p.serialize();
// Serialize velocity.
// ...
}
point p;
float v[3];
};
serializable
中的问题
根据您对 serializable
的示例用法判断,行:
void dump(void* data) { std::memcpy(data, this, serializable<T>::size_of()); }
void load(void* data) { std::memcpy(this, data, serializable<T>::size_of()); }
将导致未定义的行为。派生的 classes 不是 TriviallyCopyable。在此类类型上使用 std::memcpy
会立即导致问题。
查看 的答案。
我正在努力提供一组需要结构感知的序列化方法。因此,我构建了一个 class 模板,为所有从它继承的 class 提供这些方法。
这是我现在拥有的:
template<typename T>
class serializable
{
protected:
serializable() = default;
public:
size_t size_of() { return sizeof(T); }
void dump(void* data) { std::memcpy(data, this, serializable<T>::size_of()); }
void load(void* data) { std::memcpy(this, data, serializable<T>::size_of()); }
virtual void serialize()
{
std::cout << "Default serialize : size " << serializable<T>::size_of() << std::endl;
}
};
struct point : public serializable<point>
{
float p[3];
};
struct particle : public point, public serializable<particle>
{
float v[3];
};
int main()
{
particle p;
p.serialize();
return 0;
}
问题是在调用 p.serialize
时,编译器在 serializable<point>::serialize()
和 serializable<particle>::serialize()
之间发出不明确的重载错误。
我该如何解决这个问题?有什么方法可以覆盖 serializable<point>
的继承,只考虑 serializable<particle>
?我应该考虑另一种方法吗?
你可以把你想要的 serialize
带进来:
struct particle : public point, public serializable<particle>
{
using serializable<particle>::serialize;
float v[3];
};
但您可能只想使用组合:
struct particle : public serializable<particle>
{
point p;
float v[3];
};
How can I solve this ?
覆盖 particle
中的 serialize()
。无论如何,您都需要序列化点数据和粒子自己的数据。基础 class 的 serialize
的默认实现将无法为 particle
.
出于同样的原因,您还需要覆盖 point
中的 serialize()
。
此外,我认为将 point
作为 particle
的基础 class 似乎不正确。 particle
不是 point
。它有一个位置和速度。聚合对我来说似乎是更好的方法。
struct point : public serializable<point>
{
void serialize()
{
// Serialize p
// ...
}
float p[3];
};
struct particle : public serializable<particle>
{
void serialize()
{
// Serialize location.
p.serialize();
// Serialize velocity.
// ...
}
point p;
float v[3];
};
serializable
根据您对 serializable
的示例用法判断,行:
void dump(void* data) { std::memcpy(data, this, serializable<T>::size_of()); }
void load(void* data) { std::memcpy(this, data, serializable<T>::size_of()); }
将导致未定义的行为。派生的 classes 不是 TriviallyCopyable。在此类类型上使用 std::memcpy
会立即导致问题。
查看