2017-03-08 45 views
1

性能是在我的应用固定大小的std :: vector在运行时?

关键我需要的东西,就像std::experimental::dynarray,所以它的大小是在运行时决定的数组。

所以我想过使用一个包装类std::vector,给予其所有功能,但没有可能打电话resizereservepush_back。用几句话说,所有的方法来改变它的大小(请记住我,如果我错过了其中的一些)。

于是我开始写这个类:

CCVector.hpp

template <typename T> 
class CCVector{ 
public: 
    CCVector(size_t size); 
    T &operator[](typename std::vector<T>::size_type idx); 
private: 
    std::vector<T> v; 
}; 

CCVector.cpp

template<typename T> 
CCVector<T>::CCVector(size_t size) : v(size){} 
template<typename T> 
T& CCVector<T>::operator[](typename std::vector<T>::size_type idx){ 
    return v[idx]; 
} 

但我这一点,我想我必须重新实现的std::vectorevery方法我需要!例如begin,end,size等,我不知道如何实现所有这些...此外,这对维护非常不利:只要我需要一个来自std::vector的新方法,我需要重新实现它在CCVector

所有这一切都是因为我想在运行时固定大小的数组。如何在不使用非标准std::experimental::dynarray的情况下解决此问题?

+2

只需从std :: vector继承,然后为您希望在公开部分中公开的每个函数执行using语句。然后在专用部分对所有要禁用的功能执行using语句。 –

+1

你也可以使用[这里]的代码(http://stackoverflow.com/a/15832431/4342498) – NathanOliver

+0

@AlexZywicki,不,不要那样做;看到[你不应该从'std :: vector']继承](http://stackoverflow.com/questions/4353203/thou-shalt-not-inherit-from-stdvector) –

回答

6

使用私有继承,然后使用声明using导入您想要的函数,以将您想要的名称引入您的类。

template<class T> 
class MyVector : private std::vector<T> 
{ 
public: 
    using std::vector<T>::end; 
    // etc 
}; 

+1

这正是我的意思。 –

+0

这是一个很好的解决方案吗?正如我在更新后的问题中所写的,性能在我的应用程序中至关重要 – justHelloWorld

+1

@justHelloWorld这与使用'std :: vector'一样快。 – Galik

0

你是正确的,std::vector有(有私有继承你不没有虚析构函数这是大多数人不喜欢从标准集装箱继承的原因矢量得到问题)相当多的成员函数需要暴露给外部,但没有很多。例如,看到这里http://www.cplusplus.com/reference/vector/vector/

此外,你不需要(也不应该)自己实现std::vector - 依靠经过测试的快速代码,像STL几乎总是更好的选择。

因此,而不是重新实现,简单的“前进”的功能外,像这样:

iterator begin() 
{ 
    return v.begin(); 
} 

这是一个位的样板代码,但是如果你不调整大小功能,做一次std::vector,你完成了。

编辑:

另外,不要从 std::vector继承。这是一个坏主意,原因很多。

好的,我在这里有点快,对不起。正如评论和this post所暗示的那样,从STL容器继承并不是天生就不好。特别是如果您使用私有继承,它可能只是给定任务的有效解决方案。

+2

从矢量继承是一个坏主意,原因很多?没有人愿意解释的理由比“不这样做”,这很糟糕“ –

+1

@AlexZywicki相当。我见过的主要原因是虚拟破坏,但这是可以避免的。 “用户不知道如何使用该类”等其他内容并不特定于此。 luc如果您列出了从标准容器继承的问题,则OP可以自行决定是否适用于他们的情况。 –

+0

@AlexZywicki我不知道*许多原因,但是我知道* public *继承是危险的,因为它意味着* std :: unique_ptr > ptr = new derived'是可以的,当它实际上有UB。 – user2079303

0

私自继承std::vector正如在其他答案中提出的是一种方法。

使用可调整大小的容器时,会存在一些内存开销,其中不可调整大小就足够了。 std::vector通常约为数据指针的约4倍大小。您可以存储一个数据指针+长度的一半:

template<class T> 
class dynarray 
{ 
    std::unique_ptr<T[]> data; 
    T*     end; // or size_t size 

    //TODO functions 
}; 

的明显缺点是,你必须重新实现所有的样板,你可以以其他方式从std::vector继承。也就是说,所有的样板都很简单 - 只有很多。