如何创建 class 的唯一指针向量
How to create a vector of unique pointers of a class
我正在查看使用 new 和 delete 为 类 创建指针的代码,我正在尝试更新代码以使用唯一指针。这是我的代码。
#include <iostream>
#include <memory>
#include <vector>
class Algorithm
{
private:
public:
virtual void runn_algo() = 0;
virtual ~Algorithm() {};
};
class Algo1 : public Algorithm
{
void runn_algo()
{
std::cout << "running Algo1" << std::endl;
}
};
class Algo2 : public Algorithm
{
void runn_algo()
{
std::cout << "running Algo2" << std::endl;
}
};
class runner
{
public:
void runn_algo(std::unique_ptr<Algorithm> upa)
{
upa->runn_algo();
}
};
int main()
{
std::vector<std::unique_ptr<Algorithm>> algos;
algos.emplace_back(std::make_unique<Algo1>());
algos.emplace_back(std::make_unique<Algo1>());
algos.emplace_back(std::make_unique<Algo2>());
runner run;
for (auto i = 0u; i < algos.size(); ++i)
{
run.runn_algo(algos[i]);
}
}
我收到以下错误:
call to implicitly-deleted copy constructor of 'std::unique_ptr<Algorithm>'
run.runn_algo(algos[i]);
我不确定为什么会这样。带有原始指针的代码工作正常
class runner
{
public:
void runn_algo(Algorithm* upa)
{
upa->runn_algo();
}
};
int main()
{
std::vector<Algorithm*> algos;
algos.push_back(new Algo1());
algos.push_back(new Algo1());
algos.push_back(new Algo2());
runner run;
for (auto i = 0u; i < algos.size(); ++i)
{
run.runn_algo(algos[i]);
}
}
如错误消息所示,unique_ptr
没有复制构造函数,因此不能按值传递给函数。您可以更改签名以接受 const std::unique_ptr<Algorithm>&
引用:
class runner
{
public:
void runn_algo(const std::unique_ptr<Algorithm>& upa)
{
upa->runn_algo();
}
};
产生输出
running Algo1
running Algo1
running Algo2
符合预期。
或者,以不关心 Algorithm
存储方式的方式编写 runner::runn_algo
:
class runner
{
public:
void runn_algo(Algorithm& algo)
{
algo.runn_algo();
}
};
int main()
{
std::vector<std::unique_ptr<Algorithm>> algos;
algos.emplace_back(std::make_unique<Algo1>());
algos.emplace_back(std::make_unique<Algo1>());
algos.emplace_back(std::make_unique<Algo2>());
runner run;
for (auto i = 0u; i < algos.size(); ++i)
{
run.runn_algo(*algos[i]); // Dereference operator on algos[i]
}
}
首先,您的 emplace_back
实际上应该是 push_back
,因为您使用的是 make_unique
algos.push_back(std::make_unique<Algo1>());
algos.push_back(std::make_unique<Algo1>());
algos.push_back(std::make_unique<Algo2>());
其次你应该使用 virtual
和 override
让你的方法多态
virtual void runn_algo(); // base
void runn_algo() override; // derived
第三,您可能应该将参数作为原始(非拥有)指针传递给您的 runner
,因为如果您尝试按值传递 unique_ptr
,它会尝试复制,这unique_ptr
不允许
void runn_algo(std::unique_ptr<Algorithm> alg); // nope, cannot copy
void runn_algo(Algorithm* alg); // ok, non-owning
for (auto i = 0u; i < algos.size(); ++i)
{
run.runn_algo(algos[i].get()); // access underlying pointer
}
虽然在这种情况下,我真的不明白 runner
的意义,因为您可以在这里使用多态性
for (auto& alg : algos)
{
alg->run_algo(); // will be polymorphic
}
我正在查看使用 new 和 delete 为 类 创建指针的代码,我正在尝试更新代码以使用唯一指针。这是我的代码。
#include <iostream>
#include <memory>
#include <vector>
class Algorithm
{
private:
public:
virtual void runn_algo() = 0;
virtual ~Algorithm() {};
};
class Algo1 : public Algorithm
{
void runn_algo()
{
std::cout << "running Algo1" << std::endl;
}
};
class Algo2 : public Algorithm
{
void runn_algo()
{
std::cout << "running Algo2" << std::endl;
}
};
class runner
{
public:
void runn_algo(std::unique_ptr<Algorithm> upa)
{
upa->runn_algo();
}
};
int main()
{
std::vector<std::unique_ptr<Algorithm>> algos;
algos.emplace_back(std::make_unique<Algo1>());
algos.emplace_back(std::make_unique<Algo1>());
algos.emplace_back(std::make_unique<Algo2>());
runner run;
for (auto i = 0u; i < algos.size(); ++i)
{
run.runn_algo(algos[i]);
}
}
我收到以下错误:
call to implicitly-deleted copy constructor of 'std::unique_ptr<Algorithm>'
run.runn_algo(algos[i]);
我不确定为什么会这样。带有原始指针的代码工作正常
class runner
{
public:
void runn_algo(Algorithm* upa)
{
upa->runn_algo();
}
};
int main()
{
std::vector<Algorithm*> algos;
algos.push_back(new Algo1());
algos.push_back(new Algo1());
algos.push_back(new Algo2());
runner run;
for (auto i = 0u; i < algos.size(); ++i)
{
run.runn_algo(algos[i]);
}
}
如错误消息所示,unique_ptr
没有复制构造函数,因此不能按值传递给函数。您可以更改签名以接受 const std::unique_ptr<Algorithm>&
引用:
class runner
{
public:
void runn_algo(const std::unique_ptr<Algorithm>& upa)
{
upa->runn_algo();
}
};
产生输出
running Algo1
running Algo1
running Algo2
符合预期。
或者,以不关心 Algorithm
存储方式的方式编写 runner::runn_algo
:
class runner
{
public:
void runn_algo(Algorithm& algo)
{
algo.runn_algo();
}
};
int main()
{
std::vector<std::unique_ptr<Algorithm>> algos;
algos.emplace_back(std::make_unique<Algo1>());
algos.emplace_back(std::make_unique<Algo1>());
algos.emplace_back(std::make_unique<Algo2>());
runner run;
for (auto i = 0u; i < algos.size(); ++i)
{
run.runn_algo(*algos[i]); // Dereference operator on algos[i]
}
}
首先,您的 emplace_back
实际上应该是 push_back
,因为您使用的是 make_unique
algos.push_back(std::make_unique<Algo1>());
algos.push_back(std::make_unique<Algo1>());
algos.push_back(std::make_unique<Algo2>());
其次你应该使用 virtual
和 override
让你的方法多态
virtual void runn_algo(); // base
void runn_algo() override; // derived
第三,您可能应该将参数作为原始(非拥有)指针传递给您的 runner
,因为如果您尝试按值传递 unique_ptr
,它会尝试复制,这unique_ptr
void runn_algo(std::unique_ptr<Algorithm> alg); // nope, cannot copy
void runn_algo(Algorithm* alg); // ok, non-owning
for (auto i = 0u; i < algos.size(); ++i)
{
run.runn_algo(algos[i].get()); // access underlying pointer
}
虽然在这种情况下,我真的不明白 runner
的意义,因为您可以在这里使用多态性
for (auto& alg : algos)
{
alg->run_algo(); // will be polymorphic
}