gpt4 book ai didi

c++ - 防止在复制构造函数中切片

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:19:36 26 4
gpt4 key购买 nike

我想复制 Foo 对象类型的 vector ,但对象可以是 Foo 的几种不同派生类型。我无法弄清楚如何在不切片的情况下进行复制。这是我的玩具代码

#include "stdafx.h"
#include <memory>
#include <vector>
#include <string>
#include <iostream>

class Foo
{
public:
Foo() { m_x = "abc"; }
Foo( const Foo &other ) { m_x = other.m_x; }
virtual std::string ToString() { return m_x; }
std::string m_x;
};

class FooDerivedA : public Foo
{
public:
FooDerivedA() : Foo() { m_y = 123; }
std::string ToString() { return m_x + ", " + std::to_string( m_y ); }
int m_y;
};

class FooDerivedB : public Foo
{
public:
FooDerivedB() : Foo() { m_z = true; }
std::string ToString() { return m_x + ", " + std::to_string( m_z ); }
bool m_z;
};

class Foos
{
public:
Foos(){}
Foos( const Foos &other )
{
for ( auto &foo : other.m_Foos )
{
// I believe this is slicing. How can I prevent this?
auto f = std::unique_ptr<Foo>( new Foo( *foo ) );
m_Foos.push_back( std::move( f ) );
}
}
void Add( std::unique_ptr<Foo> foo ) { m_Foos.push_back( std::move( foo ) ); }
std::string ToString()
{
std::string s;
for ( auto &foo : m_Foos )
{
s += foo->ToString() + "\n";
}
return s;
}
private:
std::vector<std::unique_ptr<Foo>> m_Foos;
};

int main()
{
Foos f1;
f1.Add( std::unique_ptr<FooDerivedA>( new FooDerivedA ) );
auto f2 = Foos( f1 );
std::cout << "f1:" << f1.ToString() << std::endl;
std::cout << "f2:" << f2.ToString() << std::endl;
system("pause");
return 0;
}

我不能指定类型应该是 FooDerivedA,例如:

auto f = std::unique_ptr<Foo>( new FooDerivedA( *foo ) ); 

因为它可能是 FooDerivedB。如何在不切片的情况下复制数据?

最佳答案

解决这个问题的经典方法是实现一个virtual Foo *clone() const,然后调用它而不是复制构造函数。

因此,如果我们在 x 中有一些(派生形式的)Foo 的对象,我们可以通过以下方式创建另一个对象:

 void someFunc(Foo *x)
{
Foo *copy_of_x = x->clone();
...
delete copy_of_x; // Important so we don't leak!
}

请注意,由于它是一个虚函数,我们不能在 foo 或其任何派生类型的构造函数中调用它,因为虚函数不能在构造函数中“正确”运行。

关于c++ - 防止在复制构造函数中切片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17292764/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com