Как избежать копирования конструктора в функции преобразования? - PullRequest
1 голос
/ 01 февраля 2011

Я пытаюсь конвертировать между двумя классами и избегать временного объекта.

Вот мое объявление для Square:

class CSquare
{
public:
    int dimension;
    CSquare(int dimension);

    // Conversion to Rectangle
    operator CRectangle();

    ~CSquare(void);
};

, а вот мое объявление для Rectangle:

class CRectangle
{
public:
    int length;
    int width;

    CRectangle(int length, int width);

    //Copy Constructor
    CRectangle(const CRectangle& anotherRectangle); 

    ~CRectangle(void);
};

Почему

CSquare aSquare = CSquare(10);
    CRectangle convertedRect = (CRectangle) aSquare;

вызывает конструктор копирования?

У меня есть функция преобразования:

CSquare::operator CRectangle(){
    return CRectangle(CSquare::dimension,CSquare::dimension);
}

но я 'я все еще получаю временный объект.

Как мне избежать временного объекта?

Ответы [ 8 ]

5 голосов
/ 01 февраля 2011

Вы можете избежать создания копии, написав конструктор преобразования в CRectangle:

CRectangle::CRectangle(const CSquare & sq)
    :length(sq.dimension),
     width(sq.dimension)
{}
...
...
CSquare aSquare(10);
CRectangle convertedRect(aSquare);
2 голосов
/ 01 февраля 2011

Потому что вы копируете прямоугольник.

Честно говоря, я не знаю, что еще сказать. Компиляторы могут оптимизировать вызов в случае, если вы показываете, но они не обязаны. Видимо, у тебя нет.

Редактировать ....

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

1 голос
/ 01 февраля 2011

Как мне избежать временного объекта?

Вы не делаете. Вот как работают преобразования. Временный может быть исключен (создание непосредственно в пункт назначения), но это не требуется.

Звучит так, как будто вы хотите переместить семантику в C ++ 0x. Даже тогда временный «существует», но его можно перемещать, а не копировать, что для типов, где оно имеет значение, часто гораздо эффективнее.

Является ли этот квадрат / прямоугольник действительно той ситуацией, которая вас интересует, и используется здесь только для примера?

0 голосов
/ 01 февраля 2011

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

class CRectangle
{
public:
    int length;
    int width;

    CRectangle(int length, int width);
};

class CSquare : public CRectangle
{
public:
    CSquare(int dimension) : length(dimension), width(dimension)
    {}
};
0 голосов
/ 01 февраля 2011

Я не могу сказать, какой тип объекта, о котором вы говорите, имеет временный характер.

Если квадрат, то вам нужно удалить любое оправдание для создания компилятором:

CSquare aSquare(10);

Если прямоугольник, то вы должны использовать конвертирующий конструктор вместо оператора, как предлагает @PigBen:

Rectangle::CRectangle(const CSquare & sq)
    :length(sq.dimension),
     width(sq.dimension)
{}
// And then:
CRectangle convertedRect(aSquare);
0 голосов
/ 01 февраля 2011

В общем случае это зависит от компилятора. Оптимизация возвращаемого значения выполняется большинством компиляторов. Таким образом, вместо создания временного объекта и назначения его вашему объекту, вызывается копия Ctor из вашего объекта.

Также посмотрите здесь Копирование конструктора и оптимизация возвращаемого значения

0 голосов
/ 01 февраля 2011

Я бы предположил, поскольку operator CRectangle возвращает экземпляр CRectangle, конструктор копирования вызывается для возвращаемого значения.

0 голосов
/ 01 февраля 2011

Создается временный объект CRectangle, который затем копируется в convertRect.

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