你帮我修复这段代码,printIt函数exampleA就不用了。我使用了共享指针和reference_wrapper,但是il看起来不太好。
错误结果:
1;2;23;23;23; http://cpp.sh/9yqpq
#include <iostream>
#include <vector>
#include <algorithm>
#include <list>
#include <vector>
#include <iostream>
#include <numeric>
#include <random>
#include <functional>
#include <memory>
struct obj{
int value;
};
class example
{
public:
obj _obj;
obj getVal() {return _obj;}
virtual void printIt(){
std::cout << _obj.value<< ";";
}
};
struct exampleA : public example
{
public:
virtual void printIt() override{
std::cout <<"+++ "<< _obj.value<< "-";
}
};
class Container {
std::vector<std::shared_ptr<example> > input;
public:
void add (const example& a){
input.emplace_back(std::make_shared<example>(a));
}
std::vector<std::shared_ptr<example> > getInput()
{
return input;
}
};
int main(int argc, const char* argv[])
{
example one;
one._obj = obj{1};
example two;
two._obj= obj{2};
exampleA three;
three._obj =obj{23};
Container cont;
cont.add(one);
cont.add(two);
cont.add(three);
cont.add(three);
cont.add(three);
for (std::shared_ptr<example> entry : cont.getInput() )
{
example* ref = entry.get();
ref->printIt();
}
return 0;
}
发布于 2021-07-05 12:13:14
正如注释中所指出的,您可以创建example对象,这些对象是const example& a的副本。对于object3,该a只是对基本部分的引用。这叫“切片”。
一个简单的修复方法是使用模板复制实际的参数类型:
template <typename EX>
void add (EX const& a){
input.push_back(std::make_shared<EX>(a));
}现在,当您调用cont.add(three);时,模板参数演绎将推导出EX==exampleA,std::make_shared<ExampleA>将创建一个std::shared_ptr<ExampleA>。
然后,这个指针将转换为std::shared_ptr<Example>,以适应向量。但这仍然是指向ExampleA对象的指针!这不是切片。
发布于 2021-07-05 12:28:13
这一行:
input.emplace_back(std::make_shared<example>(a));总是创建example类型的新对象,参数a是对example的const引用,因此example的隐式复制构造函数启动并有对象切片。
要正确地修复它,应该将shared_ptr直接传递给add函数:
void add(std::shared_ptr<example> a)
{
input.emplace_back(std::move(a));
}以及正确使用此函数的代码。
演示
#include <iostream>
#include <vector>
#include <algorithm>
#include <list>
#include <vector>
#include <iostream>
#include <numeric>
#include <random>
#include <functional>
#include <memory>
struct obj {
int value;
};
class example {
public:
obj _obj;
obj getVal() { return _obj; }
virtual void printIt()
{
std::cout << _obj.value << ";";
}
};
struct exampleA : public example {
public:
virtual void printIt() override
{
std::cout << "+++ " << _obj.value << "-";
}
};
class Container {
std::vector<std::shared_ptr<example> > input;
public:
void add(std::shared_ptr<example> a)
{
input.emplace_back(std::move(a));
}
std::vector<std::shared_ptr<example> > getInput()
{
return input;
}
};
int main(int argc, const char* argv[])
{
auto one = std::make_shared<example>();
one->_obj = obj{ 1 };
auto two = std::make_shared<example>();
two->_obj = obj{ 2 };
auto three = std::make_shared<exampleA>();;
three->_obj = obj{ 23 };
Container cont;
cont.add(one);
cont.add(two);
cont.add(three);
cont.add(three);
cont.add(three);
for (std::shared_ptr<example> entry : cont.getInput()) {
example* ref = entry.get();
ref->printIt();
}
return 0;
}https://stackoverflow.com/questions/68254941
复制相似问题