Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.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++;相当于继承Java集合接口(集合、映射、列表等)?还是扩展抽象集合? 我已经开始用C++编写代码,来自java背景(实际上我在我的大学学习C++,但是我们从来没有到STL等)_Java_C++_Inheritance_Stl_Containers - Fatal编程技术网

什么是C++;相当于继承Java集合接口(集合、映射、列表等)?还是扩展抽象集合? 我已经开始用C++编写代码,来自java背景(实际上我在我的大学学习C++,但是我们从来没有到STL等)

什么是C++;相当于继承Java集合接口(集合、映射、列表等)?还是扩展抽象集合? 我已经开始用C++编写代码,来自java背景(实际上我在我的大学学习C++,但是我们从来没有到STL等),java,c++,inheritance,stl,containers,Java,C++,Inheritance,Stl,Containers,不管怎么说,我已经到了在各种集合中排列数据的地步,我立即告诉自己“好的,这是一种集合;这是一个列表,或一个ArrayList;这是一个map等等。”在Java中,我只需要让我正在编写的任何类实现Set、map或List接口;但是我可能不会去继承ArrayList或HashSet之类的东西,那里的实现有点复杂,我不想把它们搞砸 现在,我在C++中(标准库)做什么?似乎不存在集合、映射、列表等的抽象基类——相当于Java接口;另一方面,标准容器的实现看起来非常糟糕。好吧,也许他们在了解它们之后就不会

不管怎么说,我已经到了在各种集合中排列数据的地步,我立即告诉自己“好的,这是一种集合;这是一个列表,或一个ArrayList;这是一个map等等。”在Java中,我只需要让我正在编写的任何类实现Set、map或List接口;但是我可能不会去继承ArrayList或HashSet之类的东西,那里的实现有点复杂,我不想把它们搞砸

现在,我在C++中(标准库)做什么?似乎不存在集合、映射、列表等的抽象基类——相当于Java接口;另一方面,标准容器的实现看起来非常糟糕。好吧,也许他们在了解它们之后就不会那么可怕了,但是假设我只是想写一些C++之类的非抽象类扩展抽象集的东西?我可以传递给任何一个函数,它需要一个集合?我该怎么做呢

我只是想澄清一下,我不一定想做Java中常见的事情。但是,另一方面,如果我有一个对象,在概念上是一种集合,我想继承一些适当的东西,得到默认的实现,并由IDE引导来实现我应该执行的那些方法。

< P> C++标准库(注:它不被称为STL)。有许多现有的容器类型:
vector
array
deque
forward\u list
set
map
multiset
multimap
无序集
无序集
无序多集
无序多集
堆栈
队列
优先级队列
。很有可能,你只想直接使用其中一种——你肯定永远不想从中得到什么。然而,在某个时刻,您可能需要实现自己的特殊容器类型,如果它与某个接口匹配,那就更好了,对吗

但是,不存在容器派生自的抽象基类。然而,C++标准为类型(有时称为概念)提供了要求。例如,如果您查看C++11标准(or)的§23.2节,您会发现容器的要求。例如,所有容器都必须有一个默认构造函数,该构造函数在固定时间内创建一个空容器。然后对(如
std::vector
)和(如
std::map
)有更具体的要求。您可以对类进行编码以满足这些要求,然后人们可以按照预期安全地使用您的容器

当然,除了容器,还有很多其他的要求。例如,该标准为不同类型的迭代器、随机数生成器等提供了需求


许多人在ISO C++委员会(实际上是研究小组8)正在考虑使这些概念成为语言的一个特征。该方案将允许您指定需要满足的类型要求,以便将这些类型用作模板类型参数。例如,您可以编写一个模板函数,如下所示:

template <Sequence_container C>
void foo(C container); // This will only accept sequence containers
// or even just:
void foo(Sequence_container container);
模板
void foo(C容器);//这将只接受序列容器
//甚至只是:
void foo(顺序容器);

<>但是,我认为这是目前你对C++的理解之外的。

< P>标准C++库已经实现了列表、映射、集合等。C++中没有一点可以再次实现这些数据结构。如果您实现类似于这些数据结构之一的内容,那么您将实现相同的概念(即,使用相同的函数名、参数顺序、嵌套类型名称等)。容器有各种概念(序列、关联容器等)。更重要的是,您将使用适当的迭代器概念公开结构的内容


注:C++不是java。不要尝试用C++编程java。如果你想编写java,程序java:它比在C++中做的要好很多。如果你想编写C++程序,程序C++,

,你需要尝试放弃java思维方式。你看,STL的美妙之处在于它通过迭代器将算法与容器分离

长话短说:将迭代器传递给您的算法。不要继承遗产

以下是所有容器:

以下是所有的算法:

您希望继承遗产的原因可能有两个:

  • 您想要重用实现(坏主意)
  • 通过使行为可用(例如,从抽象集这样的基类继承),重用现有算法
要简单地讨论第一点,如果需要存储一组对象(例如游戏场景中的一组对象),请准确地执行此操作,将这些对象的一组作为场景对象的成员。不需要子类来充分利用容器。换句话说,我们更喜欢组合而不是继承。这已经做得很死了,在Java世界中被认为是做了“正确的事情”,它在GoF手册里!同样的事情也适用于C++。 示例:

为了解决第二点,让我们考虑一个场景。你正在制作一个2D侧滚游戏,你有一个
场景
对象,带有
游戏对象
的数组。例如,这些
GameObjects
具有位置,您希望按位置对它们进行排序,并进行二进制搜索以查找最近的对象

<>在C++思想中,元素的存储和容器的操作是两个不同的事情。继续
struct GameObject {
    float x, y;

    // compare just by x position
    operator < (GameObject const& other)
    {
        return x < other.x;
    }
};

void example() {
    std::vector<GameObject> objects = {
        GameObject{8, 2},
        GameObject{4, 3},
        GameObject{6, 1}
    };
    std::sort(std::begin(objects), std::end(objects));
    auto nearestObject = std::lower_bound(std::begin(objects), std::end(objects), GameObject{5, 12});

    // nearestObject should be pointing to GameObject{4,3};
}
void example() {
    // using a raw array this time.
    GameObject objects[] = {
        GameObject{8, 2},
        GameObject{4, 3},
        GameObject{6, 1}
    };
    std::sort(std::begin(objects), std::end(objects));
    auto nearestObject = std::lower_bound(std::begin(objects), std::end(objects), GameObject{5, 12});

    // nearestObject should be pointing to GameObject{4,3};
}
template<class Key, class Compare = std::less<Key>, class Allocator = std::allocator<Key>> 
class set {
    using key_type = Key;
    using value_type = Key;
    using size_type = std::size_t;
    using difference_type = std::ptrdiff_t;
    using key_compare = Compare;
    using value_compare = Compare;
    using allocator_type = Allocator;
    using reference = value_type&;
    using const_reference = const value_type&;
    using pointer = std::allocator_traits<Allocator>::pointer;
    using const_pointer = std::allocator_traits<Allocator>::const_pointer;
    using iterator = /* depends on your implementation */;
    using const_iterator = /* depends on your implementation */;
    using reverse_iterator = std::reverse_iterator<iterator>;
    using const_reverse_iterator = std::reverse_iterator<const_iterator>

    iterator begin() const;
    iterator end() const;
    const_iterator cbegin() const;
    const_iterator cend() const;
    reverse_iterator rbegin() const;
    reverse_iterator rend() const;
    const_reverse_iterator crbegin() const;
    const_reverse_iterator crend() const;

    bool empty() const;
    size_type size() const;
    size_type max_size() const;

    void clear();

    std::pair<iterator, bool> insert(const value_type& value);
    std::pair<iterator, bool> insert(value_type&& value);
    iterator insert(const_iterator hint, const value_type& value);
    iterator insert(const_iterator hint, value_type&& value);
    template <typename InputIterator>
    void insert(InputIterator first, InputIterator last);
    void insert(std::initializer_list<value_type> ilist);

    template <class ...Args>
    std::pair<iterator, bool> emplace(Args&&... args);

    void erase(iterator pos);
    iterator erase(const_iterator pos);
    void erase(iterator first, iterator last);
    iterator erase(const_iterator first, const_iterator last);
    size_type erase(const key_type& key);

    void swap(set& other);

    size_type count(const Key& key) const;
    iterator find(const Key& key);
    const_iterator find(const Key& key) const;

    std::pair<iterator, iterator> equal_range(const Key& key);
    std::pair<const_iterator, const_iterator> equal_range(const Key& key) const;

    iterator lower_bound(const Key& key);
    const_iterator lower_bound(const Key& key) const;
    iterator upper_bound(const Key& key);
    const_iterator upper_bound(const Key& key) const;

    key_compare key_comp() const;
    value_compare value_comp() const;
}; // offtopic: don't forget the ; if you've come from Java!

template<class Key, class Compare, class Alloc>
void swap(set<Key,Compare,Alloc>& lhs, 
          set<Key,Compare,Alloc>& rhs);

template <class Key, class Compare, class Alloc>
bool operator==(const set<Key,Compare,Alloc>& lhs,
                const set<Key,Compare,Alloc>& rhs);

template <class Key, class Compare, class Alloc>
bool operator!=(const set<Key,Compare,Alloc>& lhs,
                const set<Key,Compare,Alloc>& rhs);

template <class Key, class Compare, class Alloc>
bool operator<(const set<Key,Compare,Alloc>& lhs,
               const set<Key,Compare,Alloc>& rhs);

template <class Key, class Compare, class Alloc>
bool operator<=(const set<Key,Compare,Alloc>& lhs,
                const set<Key,Compare,Alloc>& rhs);

template <class Key, class Compare, class Alloc>
bool operator>(const set<Key,Compare,Alloc>& lhs,
               const set<Key,Compare,Alloc>& rhs);

template <class Key, class Compare, class Alloc>
bool operator>=(const set<Key,Compare,Alloc>& lhs,
                const set<Key,Compare,Alloc>& rhs);
using namespace std;

ifstream file("file.txt");
string file_contents(istreambuf_iterator<char>(file),
                     istreambuf_iterator<char>{});