Что делать с оператором копирования-присваивания прокси-класса? - PullRequest
1 голос
/ 26 июня 2010

Рассмотрим следующий класс прокси:

class VertexProxy
{
public:
    VertexProxy(double* x, double* y, double* z)
    : x_(x), y_(y), z_(z) {}

    VertexProxy(const VertexProxy& rhs)
    : x_(rhs.x_), y_(rhs.y_), z_(rhs.z_) {}

    // Coordinate getters
    double x() const {return *x_;}
    double y() const {return *y_;}
    double z() const {return *z_;}

    // Coordinate setters
    VertexProxy& x(double val) {*x_ = val; return *this;}
    VertexProxy& y(double val) {*y_ = val; return *this;}
    VertexProxy& z(double val) {*z_ = val; return *this;}

    VertexProxy& operator=(const VertexProxy& rhs)
    {
        // Should it be this
        x_ = rhs.x_; y_ = rhs.y_; z_ = rhs.z_;

        // or this?
        *x_ = *rhs.x_; *y_ = *rhs.y_; *z_ = *rhs.z_;

        return *this;
    }

private:
    double* x_; double* y_; double* z_;
};

Мне нужно иметь возможность сбросить прокси, чтобы он содержал разные координатные указатели (аналогично boost::shared_ptr.reset(). Кроме того, я хотел бы иметь возможностьназначить значения координат значениям из другого прокси (например, proxy1.assign(proxy2)).

Каков смысл значения operator= в моем классе выше? Чтобы скопировать указатели rhs (мелкая копия) или rhs? Или я должен просто сделать operator= закрытым и предоставить две функции-члена, чтобы избежать неоднозначности operator=?

РЕДАКТИРОВАТЬ:

Хорошо, вот некоторая справочная информация. Я пишу обертку вокруг сторонней ГИС-библиотеки (shapelib), которая хранит координаты вершин (x, y, z, m) в отдельных массивах (вместо массива структур).Мой прокси-класс используется для того, чтобы эта структура массивов выглядела как массив структур и работает в тандеме с настраиваемым классом вершинных итераторов, что значительно облегчает работу с диапазонами вершин.

Shapelib обрабатываетуправление памятью.Все, что делает мой прокси-класс, - это другое представление о данных вершин.Когда пользователь манипулирует координатами вершины, используя мой прокси, он фактически манипулирует координатами вершины в объекте формы shapelib.

Ответы [ 4 ]

3 голосов
/ 26 июня 2010

Учитывая, что ваш конструктор копирования копирует указатели, для согласованности ваш оператор копирования должен назначать указатели.

VertexProxy& operator=(const VertexProxy& rhs)
{
    x_ = rhs.x_;
    y_ = rhs.y_;
    z_ = rhs.z_;

    return *this;
}

Было бы очень непоследовательным, если бы этот (по общему мнению сомнительный) код:

VertexProxy test( const VertexProxy& other )
{
    double tmp1, tmp2, tmp3;
    VertexProxy p1( &tmp1, &tmp2, &tmp3 );
    p1 = other;
    return p1;
}

действовал иначе:

VertexProxy test( const VertexProxy& other )
{
    double tmp1, tmp2, tmp3; // unused
    VertexProxy p1( other );
    return p1;
}
2 голосов
/ 26 июня 2010

Все довольно просто. Вы хотите, чтобы VertexProxy действовал как указатель или значение? Если вы предпочитаете, чтобы он действовал как указатель, скопируйте указатели, если вы предпочитаете, чтобы он действовал как значение, скопируйте значения. Никто не может сказать вам, что ваш класс является указателем или значением (тем более что у вас, кажется, есть что-то необычное). Если вам нужен более качественный совет, нам нужно знать, что именно удерживает настоящие удвоения и почему.

Быстрое редактирование: Мне кажется, что на самом деле, если бы вы сделали разыменование, вы бы сделали его действующим как ссылка или указатель. Однако исходная точка остается прежней.

1 голос
/ 26 июня 2010

std::bitset::reference выполняет роль, аналогичную моей VertexProxy, и может использоваться в качестве модели.

typedef std::bitset<8> Bitset;
Bitset bset1, bset2;
Bitset::reference r1(bset1[3]);
Bitset::reference r2(bset2[3]);
r1 = 1;
r2 = r1;
std::cout << "bset2 = " << bset2 << "\n";

r2 = r1 выше значений копий.

0 голосов
/ 26 июня 2010

Я бы сказал, что это зависит от того, насколько велик объект.

Если тема прокси очень велика, то использование общего указателя подсчета ссылок - путь.Просто скопируйте общий указатель в операции копирования.

Если он не такой большой, лучше использовать глубокое копирование.Меньше хлопот вокруг всех.

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