Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Где copyconstructor?


Автор: vitlic 22.2.2007, 02:02
Всем привет!

Никак  не могу понять куда пропал вызов копиконстрактора, может кто объяснит?!

Temp.h
Код

#include <iostream>

using std::ostream;
using std::endl;
using std::cout;

class Int
{
    friend const Int operator*(const Int & lhs , const Int & rhs);
    friend ostream & operator <<(ostream &,  const Int &);
public:
    Int(int i=0):num(i) { cout << "Constructor" << endl; }
    Int(const Int & rhs):num(rhs.num) 
    { cout << "CopyConstructor" << endl; }
    ~Int() { cout << "Destructor" << endl; }
private:
    int num;
};

ostream & operator<<(ostream & os, const Int & rhs)
{
    os << rhs.num << endl;
    return os;
}

const Int operator*(const Int & lhs , const Int & rhs )
{
    return Int(lhs.num*rhs.num);
}


main.cpp
Код

#include "Temp.h"

int main()
{
    Int i(100);
    Int j(2);
    Int k(i*j);   // Как я понимаю тут должен быть вызов двух конструкторов
                      // Обычного в operator* и конструктора копии
    return 0;
}



VS2005 выдает:
Код

Constructor
Constructor
Constructor
Destructor
Destructor
Destructor


Кстати если изменить код operator*  на:
Код

const Int operator*(const Int & lhs , const Int & rhs )
{
    Int temp(lhs.num*rhs.num);
    return temp;
}


нет никаких проблем:
Код

Constructor
Constructor
Constructor
CopyConstractor
Destructor
Destructor
Destructor
Destructor


пы.сы. Во время постинга кажись догнал, может это из-за оптимизации?

Автор: nickless 22.2.2007, 02:22
Скорее всего компилер инлайнит operator* на строчке Int k(i*j);, попробуй выключить оптимизацию

Автор: vitlic 22.2.2007, 02:40
Цитата(nickless @ 22.2.2007,  02:22)
Скорее всего компилер инлайнит operator* на строчке Int k(i*j);, попробуй выключить оптимизацию

Пошарил немного в студии, но не нашел, где ее выключают..
Скорее всего, насчет inline, ты прав.
Спасибо.

Автор: SaDFromSpb 22.2.2007, 15:17
Попробовал на gcc собрать без оптимизации и с флагом -fno-default-inline. Не помогло =)
Дело, может быть, и не в этом. Ведь в данном случае копирование совершенно излишне...

Автор: Daevaorn 22.2.2007, 15:39
Да, тут просто оптимизация. Вот этот объект Int(lhs.num*rhs.num) легко и изящно превращается в k

Автор: Fazil6 22.2.2007, 15:41
стандарт разрешает компиллятору преобразовывать программу с целью исключить порождение временных переменных и обращения к конструктору копирования. Большинство компилляторов С++ именно так и делают.
копирайт Дьюхерст.

Автор: vitlic 22.2.2007, 18:37
"Подобно всем языкам программирования, C++ позволяет разработчикам компиляторов применить оптимизацию для повышения  производительности генерируемого кода, и, как оказывается, в некоторых случаях вызовы конструктора и деструктора возвращаемого operator* значения можно безопасно устранить. Когда компилятор пользуется этой возможностью (а часто он так и поступает), ваша программа продолжает делать то, чего вы от нее хотите, и даже быстрее, чем ожидалось. Мэйерс

Я стормозил немного, рассматривал пример из его книги, написал код дабы проверить некоторые нюансы и застрял пытаясь понять почему так происходит, а ответ был в следующем параграфе  smile 
Отсюда вывод при чтение книг, в начале нужно дочитать, а потом уж проверять  smile  

Fazil6:
Кто такой Дьюхерст? Советуешь почитать?

Автор: Fazil6 22.2.2007, 19:50
Цитата(vitlic @  22.2.2007,  17:37 Найти цитируемый пост)
Кто такой Дьюхерст? Советуешь почитать?
 хуже не будет. однозначно

Автор: vitlic 22.2.2007, 20:07
Fazil6  пасиб за наводку, при поиске в яндексе нашел:

"..Особые благодарности Бьярну Страуструпу за постоянную помощь и поддержку и за прекрасный язык, который он подарил  нам, а  также Стивену Дьюхерсту (Stephen Dewhurst),который так  много помогал   мне   при  освоении  С++.." 
Это из предисловия "С++ для начинающих"  Липман 
видать стоит почитать! 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)