C++数据结构设计:具有不同领域和功能的儿童
C++ data structure design: children with different fields and function
我刚开始学习C++,我已经习惯了Java范式,所以我不确定应该如何做到这一点:我需要表示两种不同类型的产品向量:包装和新鲜食品。它们有一些通用字段,只有一个实现(可用性、再库存数量等),但它们也有不同字段和函数和不同的返回类型。
I.E:新鲜食品可能有一个布尔字段需要冷藏,其他产品可以具有表示类别(食品、清洁、食品等)的整数,拼凑、通奸…)。
在Java中,我会创建一个具有公共字段的Product对象和一个PackagedProduct(扩展Product)加上一个具有特定字段的FreshProduct(也扩展Product)。然后,我会将每个乘积放在一个向量中,并在需要公共字段时作为乘积访问,在需要访问子字段时安全地(使用instanceof)投射到正确的类。我知道这在C++中不是正确的方式,我不想强迫java编程范式使用C++。
我可以想象:
- 将所有cild所需的所有函数创建为父级中的虚拟函数,并在父级中添加一个表示cild类型的字段,这样就可以安全地强制执行
- 创建一个包含两个不同向量的包装器对象,每个向量都是子对象的类型,并按正确的顺序返回值,最后使用第三个int向量
我认为这些解决方案真的很糟糕,我几乎可以肯定肯定肯定有更好的方法,但我无法想象。你能帮我吗?做这件事的正确方法是什么?
我需要代表两种不同类型的产品:包装食品和新鲜食品。
你真的需要同一向量中的两种类型的乘积吗?你不能有两个矢量吗?
std::vector<PackagedProduct> packaged;
std::vector<FreshProduct> fresh;
packaged.emplace_back(1, 2, 3);
fresh.emplace_back(4, 5, 6);
这将是迄今为止最有效的解决方案。(较少的间接寻址可以让预取器满意。)
如果您绝对需要同一矢量中的两种产品,则必须使用间接:
std::vector<std::unique_ptr<Product>> products;
products.push_back(std::make_unique<PackagedProduct>(1, 2, 3));
products.push_back(std::make_unique<FreshProduct>(4, 5, 6));
与其在运行时检查动态类型并向下转换,不如阅读虚拟方法。
基本思想与Java相同:使用继承创建类层次结构:
class Product { public: virtual ~Product(); ... };
class PackagedProduct : public Product { ... };
class FreshProduct : public Product { ... };
在Java中,向量(或列表、容器…)通过引用存储,而不是通过值存储。这就是关键的区别。在C++中,这意味着使用一个智能指针:
std::vector< std::shared_ptr< Product > > v;
v.push_back( std::make_shared< FreshProduct >( some args... ) );
一旦从矢量中检索到指针,就可以使用dynamic_pointer_cast
来检查它是什么对象,但也可以使用其他选项。
当然,这只是一个粗略的想法,你需要了解很多关于细节、shared_ptr
等的信息,但我希望你现在有足够的关键词和想法来搜索:)
创建一个具有公共字段的Product对象和一个PackagedProduct(扩展Product)加上一个具有特定字段的FreshProduct(也扩展Product)。然后将指向它们的智能指针存储在:中
std::vector<std::unique_ptr<Product> > Vec;
如果FredOverflow关于使用两个向量的建议不符合您的需求,则可以选择制作两种类型的变体,并保留一个变体向量。使用boost::variant可以很容易地做到这一点。您可以将所需的功能封装在自由函数中,也可以将变体封装在类中。这里有一个的例子
#include <boost/variant/variant.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <boost/variant/static_visitor.hpp>
struct FreshProduct
{
double price;
bool needsRefrigeration;
};
struct PackagedProduct
{
double price;
};
struct VariantProduct
{
VariantProduct(const FreshProduct& p) : product(p) {}
VariantProduct(const PackagedProduct& p) : product(p) {}
double getPrice() const;
bool needsRefrigeration() const
{
struct helper : public boost::static_visitor<bool>
{
bool operator ()(const FreshProduct& product) const
{
return product.needsRefrigeration;
}
bool operator ()(...) const
{
return false;
}
};
return boost::apply_visitor(helper(), product);
}
private:
boost::variant<FreshProduct, PackagedProduct> product;
};
// in cpp
namespace {
struct GetPrice : public boost::static_visitor<double>
{
template <class T>
double operator ()(const T& product) const
{
return product.price;
}
};
} // anonymous namespace
double VariantProduct::getPrice() const
{
return boost::apply_visitor(GetPrice(), product);
}
这种方法的优点是,您不需要使用动态分配来保持新鲜或包装产品的集合。缺点是,扩展变体中支持的类型不像使用继承那样容易。
- 询问在设计我的手臂模拟器功能表示格式1
- 设计将引用元素移动到开头的数据结构.C++
- C++,您能否设计一种数据结构,将指针保存在连续内存中并且不会使它们失效?
- 面向数据的设计;如何在 C++ 中优化数据结构以提高性能?
- 设计模式,以避免不必要地添加抽象函数以适应新功能
- C++功能设计
- C++中用于结构的纯数组的类似于TableView/DataFrame的通用功能
- 有没有办法在我的通用功能路由器设计中支持"常量引用"作为功能签名参数?
- 多种搜索组合的数据结构设计
- C++虚拟功能与设计模式
- 类层次结构设计,避免从基类到派生类的向下转换
- C++类层次结构设计选择
- 类继承层次结构设计问题
- 操作员重新分配功能/结构返回什么
- 功能原型设计会影响性能吗
- 哪个功能结构更好
- 输入需要我的程序结构/设计
- 通信b/w两个线程在一个公共的数据结构.设计问题
- 类/结构设计;继承与前向声明
- C++数据结构设计:具有不同领域和功能的儿童