Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用只在构造函数中不同的类有哪些优点和缺点?_C++_Oop - Fatal编程技术网

C++ 使用只在构造函数中不同的类有哪些优点和缺点?

C++ 使用只在构造函数中不同的类有哪些优点和缺点?,c++,oop,C++,Oop,我有一个类SpecialArray,可以用与标准二维数组相同的方式访问它;i、 例如,作为A[i][j]。通常需要从该对象中提取int的一维数组。提取的细节(取决于其他传递的参数)无关紧要;我对设计操作界面感兴趣 以下完成此任务的方法的优点和缺点是什么 选项1 我们定义了一个函数: std::vector<int> extract(const SpecialArray &A, ...) 选项2 我们创建了一个从std::vector继承的类,并构造它自己: class Sp

我有一个类
SpecialArray
,可以用与标准二维数组相同的方式访问它;i、 例如,作为
A[i][j]
。通常需要从该对象中提取
int
的一维数组。提取的细节(取决于其他传递的参数)无关紧要;我对设计操作界面感兴趣

以下完成此任务的方法的优点和缺点是什么

选项1

我们定义了一个函数:

std::vector<int> extract(const SpecialArray &A, ...)
选项2

我们创建了一个从std::vector继承的类,并构造它自己:

class SpecialArrayExtract : public std::vector<int> {
    public:
        SpecialArrayExtract(const SpecialArray &A, ...);
};
选项3

我们完全按照选项2进行操作,但不继承自
std::vector
,而是拥有一个
private
成员
std::vector
,根据需要公开接口:

class SpecialArrayExtract {
    private:
        std::vector<int> m_data;
    public:
        SpecialArrayExtract(const SpecialArray &A, ...);
        [Wrapper functions for std::vector<int> here.]
};
class SpecialArrayExtract{
私人:
std::向量m_数据;
公众:
特殊射线提取物(const Speciallarray&A,…);
[此处是std::vector的包装函数。]
};
评论

该应用程序是高性能的,但是在选项1中使用RVO时,我假设这些应用程序的性能应该是相等的


将此与标题联系起来,我想指出的一点是,选项2和3都定义了一些类,这些类本质上只是
std::vector
,具有不同的名称和特殊的构造函数。什么时候——如果有的话!——这是一个合理的想法吗?哪种方法更好?

选项4

为类SpecialArray实现公共成员函数:

std::vector<int> extract(...);
std::向量提取(…);

我认为选项一最有意义,因为它:

  • 有一个非常简单的接口
  • 不创建其他类
  • 可以通过模板扩展其他“提取”操作
我反对选项二,因为如果你从
std::vector
继承,你是说
specialrayextract
是-a
std::vector
,并提供一个单独的操作(构造函数)来创建它。如果你想一想,这只是一个复杂的方式来做完全一样,你的第一个选择

选项三似乎是一个过早的优化(您选择的是包含而不是继承,好像您会先发制人地期望底层数据容器发生变化),这比选项二更复杂

至于选项4(在回答中建议),我认为类接口应该保留尽可能少的实例方法,而不是提供非成员函数(请参阅了解基本原理)

如果将来需要更改(例如,您决定另一个容器或数据类型更好地满足您的需要),您可以通过模板修改函数。这将为您提供拥有单独类的所有优势,但不会增加开销。相同的操作(具有完全相同的名称)可以应用于任何可能的容器类型组合(即,
std::vector
,或
std::array
,或其他)和数组类型(
specialray
,或
SparseSpecialArray
,或其他):

模板
ContainerType提取(常量数组类型和数组,…)

最后,您可以创建一个单独的
算法
命名空间,其中包含作用于
数组类型
数据的所有函数(例如,
SpecialArray
)。这将使记录和维护代码变得非常简单:数据类型的所有通用操作都存在于
算法中::
,对于此类操作,命名空间是一个更自然的聚合器,而不是一个具有许多静态方法的类。

我个人只需实现一个ToVector(…)方法在SpecialArray类中。如果您没有访问源代码的权限(我相信您有),您可以将该方法作为扩展添加到该类中

据我所知,你的问题是你的内存中有一个特殊的数组,你想把它转换成std::vector。如果这两个类在内存中都是隔离的(即没有缓存来提高转换性能),那么您只需要一个方法来获取SpecialArray并将其转换为std::vector。不管它是构造函数还是常规方法,只要SpecialArray是通过引用传递的

template < typename OutIt >
void extract(SpecialArray const&, OutIt dest_begin);
例如:

SpecialArray my_special;

constexpr std::size_t len = 100;
int                  dest_ra[len];
std::array<int, len> dest_a;
std::vector<int>     dest_v;
std::list<int>       dest_l;

if( len >= my_special.extract_length() )
{
    extract( my_special, std::begin(dest_ra) );
    extract( my_special, std::begin(dest_a) );
}

// using `push_back`:
  dest_v.reserve( my_special.extract_length() );       // not necessary
  extract( my_special, std::back_inserter(dest_v) );

  extract( my_special, std::back_inserter(dest_l) );

// if random access is required, also a bit faster(*):
  dest_v.resize( my_special.extract_length() );
  extract( my_special, std::begin(dest_v) );

  // not possible for the list
specialray my_special;
constexpr std::size\u t len=100;
内部目的地[列];
std::数组dest_a;
std::向量dest_v;
标准:列出目的地;
如果(len>=my_special.extract_length())
{
摘录(my_special,std::begin(dest_ra));
摘录(my_special,std::begin(dest_a));
}
//使用“推回”:
dest_v.reserve(my_special.extract_length());//没必要
摘录(my_special,std::back_inserter(dest_v));
摘录(my_special,std::back_inserter(dest_l));
//如果需要随机访问,也要快一点(*):
dest_v.resize(my_special.extract_length());
摘录(my_special,std::begin(dest_v));
//对于列表来说不可能
(*)
back\u insert\u迭代器必须进行范围检查以放大向量。如果使用普通迭代器,则不进行范围检查



我喜欢Arrieta的论证,并同意对选项的判断。

那么您有一个包含多个数组的数据结构,并且需要提供对整个数组的访问?提取方法从内部存储的数组复制到目标数组(无论是RVO还是move语义);真的有必要复制它吗?选项2非常糟糕,您不应该公开继承std::vector,因为它没有虚拟析构函数…@DyP提取的数组是原始多维数组中的元素序列,这些元素是
template<typename ContainerType, typename ArrayType>
ContainerType extract(const ArrayType& array, ...)
template < typename OutIt >
void extract(SpecialArray const&, OutIt dest_begin);
std::size_t extract_size() const;
SpecialArray my_special;

constexpr std::size_t len = 100;
int                  dest_ra[len];
std::array<int, len> dest_a;
std::vector<int>     dest_v;
std::list<int>       dest_l;

if( len >= my_special.extract_length() )
{
    extract( my_special, std::begin(dest_ra) );
    extract( my_special, std::begin(dest_a) );
}

// using `push_back`:
  dest_v.reserve( my_special.extract_length() );       // not necessary
  extract( my_special, std::back_inserter(dest_v) );

  extract( my_special, std::back_inserter(dest_l) );

// if random access is required, also a bit faster(*):
  dest_v.resize( my_special.extract_length() );
  extract( my_special, std::begin(dest_v) );

  // not possible for the list