C ++: контейнер оригинальных указателей - PullRequest
0 голосов
/ 27 сентября 2010

Мне нужно хранить ссылки на экземпляры производных классов в C ++. Я рассмотрел использование вектора shared_ptrs для базового класса (поскольку он должен содержать различные типы производных классов), однако важно, чтобы контейнер содержал исходные указатели, что не относится к векторам (или другим контейнерам stl) если я не ошибаюсь. Есть ли способ сделать это в нативном C ++ или мне нужно использовать специальные контейнеры, такие как Boost's ptr_vector?

РЕДАКТИРОВАТЬ: Это мой тестовый код:

class Foo
{
public:
    Foo() {}
    virtual ~Foo() {}
    virtual void set_x(int i) = 0;
};

class Bar : public Foo
{
public:
    Bar() {}

    void set_x(int i)
    {
        this->x = i;
    }

    int x;
};

int main()
{
    Bar bar;

    // ptr
    std::cout << &bar << "\n";

    std::vector<Foo*> foos;
    foos.push_back(&bar);

    // different ptr value
    std::cout << &foos[0] << "\n";

    foos[0]->set_x(1);

    // however, changes are made
    std::cout << bar.x;

    return 0;
}

Заранее спасибо,

Jena

Ответы [ 3 ]

1 голос
/ 27 сентября 2010

Вы можете создать std :: vector, который будет содержать любые указатели на то, что вы передаете ему.Он не будет предпринимать какие-либо попытки удалить те указатели на уничтожение, которые могут быть, а могут и не совпадать с вашими, но он будет содержать именно те значения, которые вы передаете.создайте std :: vector >, в котором будут храниться указатели, которые будут выпущены, когда нет висящих копий shared_ptr.Они также будут содержать «оригинал» foo *, который вы прошли;вы можете получить его снова с помощью метода shared_ptr :: get ().

Единственный раз, когда вы не увидите точно такой же указатель, как у вашего производного объекта, это если вы используете множественное наследование классов, иваши базовые классы включают в себя данные.Потому что в этом случае foo * в конечном итоге будет указывать на часть данных «foo», которая не обязательно должна быть в «корне» объекта.

1 голос
/ 27 сентября 2010

В приведенном выше примере распечатывается адрес указателя, а не значение указателя.

Вместо:

// different ptr value
std::cout << &foos[0] << "\n";

Do

// different ptr value
std::cout << foos[0] << "\n";

Кроме того, ваш vector<Foo*> будет отлично работать.

0 голосов
/ 27 сентября 2010

Если вы используете shared_ptr в качестве члена контейнера, указатель в каждом члене сохранит доступ к исходному экземпляру объекта.Вы можете получить копию shared_ptr в любой момент после обработки контейнера, но исходный объект по-прежнему будет его целью.

Для более простого решения вы можете использовать boost::ptr_vector, если ни один из ваших указателей не встречаетсядважды в контейнере - этот сценарий привел бы к сложной сложности управления ресурсами и вернул бы вас к shared_ptr.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...