Интерфейс/Суперкласс для Наборов/Контейнеров в C++

Другое основное отличие состоит в том, что переменные таблицы не имеют статистики столбцов, в отличие от временных таблиц. Это означает, что оптимизатор запросов не знает, сколько строк находится в табличной переменной (он угадывает 1), что может привести к генерации крайне неоптимальных планов, если переменная таблицы на самом деле имеет большое количество строк.

10
задан Janusz 23 July 2009 в 21:09
поделиться

4 ответа

Концепция контейнера воплощается в итераторах.
Как вы видели, жесткое кодирование конкретного типа контейнера, вероятно, не то, что вам нужно. Так что сделайте так, чтобы ваш класс возвращал итераторы. Затем вы можете повторно использовать итераторы conatiners.

class MyClass
{
    private:
        typedef  std::list<int>            Container;
    public:
        typedef  Container::iterator       iterator;
        typedef  Container::const_iterator const_iterator; 


        iterator        begin()        {return myData.begin();}
        const_iterator  begin() const  {return myData.begin();}

        iterator        end()          {return myData.end();}
        const_iterator  end()   const  {return myData.end();}

    private:
        Container   myData;
};

Теперь, когда вы меняете тип контейнера с std :: list на std :: set, никому не нужно знать.
Также при использовании стандартных имен, которые используют другие контейнеры, ваш класс начинает выглядеть как любой другой контейнер из STL.

Примечание: метод, возвращающий const_iterator, должен быть методом const.

10
ответ дан 3 December 2019 в 16:54
поделиться

Вся стандартная библиотека C ++, включая ее контейнеры, - в отличие от Java - не интерфейс (наследование, полиморфизм), а основана на шаблонах (ради эффективности).

Вы можете создать полиморфная оболочка вокруг вашей коллекции, но это не способ C ++.

Самое простое решение - просто упростить программу с помощью некоторых псевдонимов типов:

#include <iostream>
#include <list>
#include <vector>

using namespace std;

class Test {

private:
    typedef vector<int> Collection;

    Collection c;

public:

    typedef Collection::const_iterator It;

    void insert(int Item) {
        c.push_back(Item);
    }

    It begin() const { return c.begin(); }
    It end()   const { return c.end(); }

};

int main() {

    Test foo;

    foo.insert(23);
    foo.insert(40);

    for (Test::It i = foo.begin(); i != foo.end(); ++i)
        cout << *i << endl;

    return 0;
}

Теперь вы можете изменить Collection -typedef без необходимости ничего менять. (Примечание: если вы сделаете Коллекцию общедоступной, пользователь сможет ссылаться на тип, который вы явно использовали)

10
ответ дан 3 December 2019 в 16:54
поделиться

From your description I think the short answer is no.

In general when I'm creating some form of collection like this I would normally use a typedef to specify the container that I'm using:

class Object {
   typedef std::list<int> Cont;
   typedef Cont::iterator iterator;
   typedef Cont::const_iterator const_iterator;

   // ....
};

All client code refers to "Object::Cont" etc. and so as long as clients only use the general features of containers, they will not need to change if the container changes.

If you cannot change your API now, then I think your solution is pretty good, however, depending on the data that you have, if you do a lot of inserts that tend to be unique, then it may be more efficient to continue using the list and only remove duplicates at the end:

void foo (std::list<int> & list) {

  // ... fill the list

  list.sort ();
  list.unique (); 
}
2
ответ дан 3 December 2019 в 16:54
поделиться

No interface exists. Instead, you would typically use templates, and simply say "I don't care what type it is, as long as it behaves as a container".

Assuming your function looks like this:

std::list<int> DoStuff()

it can be called like this:

template <typename container_type>
void caller() {
  container_type result = DoStuff();
}

Only the first function has to be changed if you decide to return a set instead. The calling function doesn't really care (as long as you don't rely on the specifics of a list, of course).

If you post a bit more sample code, we might be better able to suggest how it should be done in C++.

2
ответ дан 3 December 2019 в 16:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: