抽象类和独特的指针
Abstract class and unique pointer
我的代码中有以下错误:
error: allocating an object of abstract class type 'Material'
我不知道如何处理这种情况。
我知道std::make_unique
执行分配,因此不能分配类型Material
的对象,但是我不知道如何纠正它。
#include <iostream>
#include <memory>
struct Material
{
Material() = default;
virtual int get_color() const = 0;
};
struct Basic : public Material
{
Basic() = default;
virtual int get_color() const override
{
return 1;
}
};
struct Mix : public Material
{
Mix(const Material& mat1, const Material& mat2)
: mat1_(std::make_unique<Material>(mat1))
, mat2_(std::make_unique<Material>(mat2))
{}
virtual int get_color() const override
{
return mat1_->get_color() + mat2_->get_color();
}
private:
std::unique_ptr<Material> mat1_;
std::unique_ptr<Material> mat2_;
};
int main()
{
auto mix = Mix(Basic(), Basic());
std::cout << mix.get_color() << 'n';
}
此调用:
std::make_unique<Material>(mat1)
试图创建一个Material
类的实例,这是mat1
类型无关的。您似乎需要班上的方法clone()
:
class Material {
...
virtual std::unique_ptr<Material> clone() const = 0;
};
然后Mix
CTOR将是:
Mix(const Material& mat1, const Material& mat2)
: mat1_(mat1.clone())
, mat2_(mat2.clone())
{}
您需要在每个派生类中实现clone()
:
struct Basic : public Material
{
Basic() = default;
virtual std::unique_ptr<Material> clone() const override
{
return std::make_unique<Basic>( *this );
}
virtual int get_color() const override
{
return 1;
}
};
问题是因为Mix
试图创建一个抽象类Material
的对象:
: mat1_(std::make_unique<Material>(mat1))
理想情况下,基于签名
Mix(const Material& mat1, const Material& mat2)
Mix
应该能够仅在传递给它的任何类型的Material
上操作。
通过抽象类参考传递Mix
的事实很好。但是Mix
试图创建派生类的对象的事实是不寻常的。如果还有其他派生类怎么办?
我的设计略有不同,使得 Mix
不是是成员的所有者。它们是由外面的东西创建和拥有的,Mix
只需将传递给它的内容混合。
struct Mix : public Material
{
Mix(const Material& mat1, const Material& mat2)
: mat1_{mat1}, mat2_{mat2}
{}
virtual int get_color() const override
{
return mat1_.get_color() + mat2_.get_color();
}
private:
Material const& mat1_;
Material const& mat2_;
};
int main()
{
std::unique_ptr<Material> mat1 = std::make_unique<Basic>();
std::unique_ptr<Material> mat2 = std::make_unique<Basic>();
auto mix = Mix(*(mat1.get()), *(mat2.get()));
std::cout << mix.get_color() << 'n';
}
您可以使用模板构造函数安排构造正确类型的情况,而无需克隆方法:
#include <iostream>
#include <memory>
struct Material {
Material() = default;
virtual int get_color() const = 0;
};
struct Basic : Material {
Basic() = default;
int get_color() const override {
return 1;
}
};
struct Mix : Material {
template<typename M1, typename M2>
Mix(const M1& mat1, const M2& mat2)
: mat1_{std::make_unique<M1>(std::move(mat1))}
, mat2_{std::make_unique<M2>(std::move(mat2))}
{}
int get_color() const override {
return mat1_->get_color() + mat2_->get_color();
}
private:
std::unique_ptr<Material> mat1_;
std::unique_ptr<Material> mat2_;
};
int main() {
auto mix = Mix(Basic(), Basic());
std::cout << mix.get_color() << 'n';
}
请注意,仅当您发送带有已知类型的材料的实例时才有效。
http://www.cplusplus.com/forum/beginner/236974/包含适当的解决方案。make_shared
和make_unique
应为特定类型;然后,您可以在没有问题的情况下将其存储在抽象类型的shared_ptr
或unique_ptr
中。
相关文章:
- 如何将子类作为函数的参数传递给期望基类,然后将该对象传递到指向这些抽象类对象的指针向量中?
- 两个抽象类,派生自同一个基类.如何访问从一个抽象类到另一个抽象类的指针
- 删除指向抽象类的指针向量
- 如何将抽象类指针作为Q_PROPERTY?
- 为什么我可以取消引用指向抽象类的指针?
- 指向抽象类的指针数组:指向 nullptr 或不指向 nullptr (C++)
- C++ abort() 在函数内的抽象类对象指针调用上
- 抽象类和独特的指针
- 如何使用抽象类指针避免内存泄漏
- 如何从抽象类中删除指针
- 指向模板抽象类的指针向量
- 指针到抽象类的功能超载
- 使用抽象类时,如何正确删除指针
- 抽象类和唯一指针 c++ 错误
- 尝试在映射C++中存储指向抽象类的指针
- 如何使用 Rcpp 公开抽象类的指针?
- 抽象类和指针
- 重写指向抽象类的指针的引用值无效
- 使用智能指针将右值引用绑定到抽象类的替代方法
- 指向抽象类的指针