避免在方法调用中进行对象切片
Avoiding object slicing in a method call
我一直在尝试重写我的程序,以允许继承类。我遇到了切片的问题。我最初在Test
类中有Parent m_parent
(因此在Test中没有动态分配),但我认为它可以解决我的问题,但它没有。我不知道我是在让我的问题变得更糟,还是像写一个复制构造函数(或其他简单的修复程序)一样简单。
class Parent
{
public:
Parent();
private:
string a;
};
class Child : public Parent
{
private:
string b;
};
class Test
{
public:
Test()
{
m_parent = new Parent;
}
void testFunction(Parent &parent)
{
*m_parent = parent;
}
~Test()
{
delete m_parent;
}
private:
Parent * m_parent;
};
这样做仍然会导致切片。。。
Child c("foo", "bar");
Parent * p = &c;
Test.testFunction(*p);
没有对象切片,但m_parent
不会变成Child
,只复制string a
。
如果你想在Test
中保存一份,我建议使用Clone
:
class Parent
{
public:
virtual ~Parent() = default;
virtual Parent* Clone() const { return new Parent(*this); }
private:
string a;
};
class Child : public Parent
{
public:
Child* Clone() const override { return new Child(*this); }
private:
string b;
};
class Test
{
public:
void testFunction(const Parent &parent)
{
m_parent.reset(parent.Clone());
}
private:
std::unique_ptr<Parent> m_parent;
};
是。此行:
*m_parent = parent;
导致对象被分割成Parent
对象,而不管它到底是什么。
除此之外,在您的示例中还有许多错误代码行,但我想这只是因为这是一个非常具体的问题。
编辑:如何避免切片的建议:
template <class T>
void testFunction(T& t){
static_assert(std::is_base_of<Parent,T>::value,"only subclasses of Parent may be passed to testFunction");
delete m_parent;
m_parent = new T(t); //or: new T(std::move(t));
}
第2版:如果您将子对象作为真实对象而不是父指针传递,也就是testFunction(myChild)
,那么这将起作用
EDIT3:@Jarod42对clone
方法有很好的看法。这两种解决方案可以一起使用
相关文章:
- 避免矢量中的对象切片<Base><shared_ptr>
- 专门化模板覆盖函数/避免对象切片
- C++ 被此代码与多态性、指针和对象切片混淆
- 我们能胜过对象切片吗?
- 如何在考虑对象切片的同时通过传入单个 Base 对象来打印出数组中的对象?
- 成员变量和对象切片
- 如何在不引入未来对象切片的情况下实现 ICloneable
- 避免对象切片
- 故意对对象切片是一种可行的技术吗?
- 对象切片:通过按值派生为 Base - 安全还是危险?
- C++ CRTP 派生类对象切片
- C++ - 即使在使用指针后也能进行对象切片
- 了解对象切片
- 使用对象切片可靠地从多个基类之一中复制
- 对象切片和隐式类型转换
- 一种克服对象切片的方法
- 按引用传递可避免对象切片
- 使用CRTP时的对象切片
- 对象切片:从基类对象访问分层的类方法
- 这会导致对象切片吗?