Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.77
2e1553ce
1 / 1 / 1
Регистрация: 16.12.2011
Сообщений: 47
#1

запуск конструкторов - C++

30.01.2012, 11:16. Просмотров 1672. Ответов 20
Метки нет (Все метки)

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class String                    
  {
  private:
    strCount* psc;              
  public:
    String()                    // конструктор 
      { psc = new strCount("NULL"); }
//---------------------------------------------------------
    String(char* s)             // конструктор
      { psc = new strCount(s); }
//---------------------------------------------------------
    String(String& S)           // конструктор
      {    
      psc = S.psc;
      (psc->count)++;
      }
 
  };
///////////////////////////////////////////////////////////
int main()
{
  String s3 = "Муха по полю пошла, муха денежку нашла";
  return 0;
}

Подскажите при создании объекта s3 будут включены все 3 конструктора ?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.01.2012, 11:16     запуск конструкторов
Посмотрите здесь:

Вызов конструкторов - C++
привет почему здесь вызывается только 1 конструктор? #include <iostream> using namespace std; class A {

Наследование конструкторов - C++
если при наследовании классов отсутствует конструктор в базовом классе, то что тогда? Помогите, не могу найти ответ в инете.

Наследование конструкторов - C++
Здравствуйте, мне нужно что бы player наследовал конструктор от aobject class aobject { public: aobject(int xx,int yy,int** mm)...

Массив из конструкторов - C++
Подскажите как создать массив из конструкторов определенного класса. Приведу пример: static int num1 = 0; ... ...

Перегрузка конструкторов - C++
Добрый день знатоки С++ возник вопрос Код этой программы компилируется в CodeBlocks а на VirtualBox не компилируется , объясните...

Наследование конструкторов - C++
Вопрос по теории наследования: Есть некоторый базовый класс с двумя конструкторами типа паблик, первый без аргумента, второй с одним...

Наследование конструкторов - C++
Добрый день. Подскажите как правильно осуществить наследование конструктора в двух файлах h и cpp. В одном h файле все работало. ...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Chelioss
179 / 179 / 4
Регистрация: 08.01.2011
Сообщений: 1,133
31.01.2012, 19:20     запуск конструкторов #16
Цитата Сообщение от OstapBender Посмотреть сообщение
кстати только вчера видел пример вызова из 1го конструктора - другого
Я вообще-то не про это.
Сыроежка
Заблокирован
31.01.2012, 21:20     запуск конструкторов #17
Цитата Сообщение от 2e1553ce Посмотреть сообщение
если комменты добавить , то запускается только второй (char* s) потом все уходит на обработку в класс StrCount.
Конструктор копии запускается при таком обявлении:
C++
1
String s2(s3);
Ну и первый соответственно при :
C++
1
String s4;
Разобрался
Увы, вы преждевременно радуетесь, что вы разобрались. На самом деле у вас некорректные представления.
Итак, рассмотрим предложение создания вашего объекта

C++
1
  String s3 = "Муха по полю пошла, муха денежку нашла";
Ваш объект типа String не может инициализироваться символьным литералом. Поэтому в вашем классе ищется конструктор, который преобразует символьный литерал в объект класса String. Такому конструктору соответствует конструктор вида String(char* s). После того, как объект класса String для выражения инициализации, стоящего в правой части знака = создан, вызывается конструктор копирования String(String(char* s)). Итак, строка

C++
1
  String s3 = "Муха по полю пошла, муха денежку нашла";
соответствует вызову двух конструкторов, то есть эквивалетна предложению

C++
1
String s3( String( "Муха по полю пошла, муха денежку нашла" ) );
Вы сейчас будете мне возражать, что вы посмотрели с помощью режима отладки, и у вас на самом деле вызвался один конструктор String(char* s).вместо двух конструкторов String(String(char* s)), как я это утверждаю.

Дело в том, что для обспечения оптимизации стандарт С++ позволяет создавать временный объект в области памяти создаваемого объекта, а потому конструктор копирования разрешается опустить. То есть стандарт С++ разрешает, что когда запускается выражение String(char* s)., то не создается временный объект, который затем является операндом конструктора копирования, а создается объект сразу в памяти, выделенной объекту s3. Но чтобы вы убедились, что наличие и доступность конструктора копирования все равно требуются, проведите такой тест: сделайте конструктор копирования закрытым и попробуйте запустить вашу программу. То есть в вашем классе поставьте объявление конструктора копирования String(String& S) в секцию private вашего класса, и вы увидите, что к вашему удивлению программа не будет компилироваться, хотя конструктор, тот, один, String(char* s), который вы считали запускается, по-прежнему является открытым членом вашего класса. String .
Это означает, что в вашем примере должны запускаться два конструктора, но в целях обспецения оптимизации стандарт С++ разрешает опускать запуск конструктора копирования, так как, фактически, оба конструктора делают одну и ту же инициализациию создаваемого объекта, а потому излишне создание временного объекта, а затем с помощью него инициализировать ваш создаваемый объект. Но при этом конструктор копирования все равно должен быть доступен для вызова, иначе вы не сможете создать свой объект, так как формально должны вызываться два конструктора, как былло указано в начале.
2e1553ce
1 / 1 / 1
Регистрация: 16.12.2011
Сообщений: 47
01.02.2012, 08:58  [ТС]     запуск конструкторов #18
Цитата Сообщение от Сыроежка Посмотреть сообщение
Увы, вы преждевременно радуетесь, что вы разобрались. На самом деле у вас некорректные представления.
Итак, рассмотрим предложение создания вашего объекта

C++
1
  String s3 = "Муха по полю пошла, муха денежку нашла";
Ваш объект типа String не может инициализироваться символьным литералом. Поэтому в вашем классе ищется конструктор, который преобразует символьный литерал в объект класса String. Такому конструктору соответствует конструктор вида String(char* s). После того, как объект класса String для выражения инициализации, стоящего в правой части знака = создан, вызывается конструктор копирования String(String(char* s)). Итак, строка

C++
1
  String s3 = "Муха по полю пошла, муха денежку нашла";
соответствует вызову двух конструкторов, то есть эквивалетна предложению

C++
1
String s3( String( "Муха по полю пошла, муха денежку нашла" ) );
Вы сейчас будете мне возражать, что вы посмотрели с помощью режима отладки, и у вас на самом деле вызвался один конструктор String(char* s).вместо двух конструкторов String(String(char* s)), как я это утверждаю.

Дело в том, что для обспечения оптимизации стандарт С++ позволяет создавать временный объект в области памяти создаваемого объекта, а потому конструктор копирования разрешается опустить. То есть стандарт С++ разрешает, что когда запускается выражение String(char* s)., то не создается временный объект, который затем является операндом конструктора копирования, а создается объект сразу в памяти, выделенной объекту s3. Но чтобы вы убедились, что наличие и доступность конструктора копирования все равно требуются, проведите такой тест: сделайте конструктор копирования закрытым и попробуйте запустить вашу программу. То есть в вашем классе поставьте объявление конструктора копирования String(String& S) в секцию private вашего класса, и вы увидите, что к вашему удивлению программа не будет компилироваться, хотя конструктор, тот, один, String(char* s), который вы считали запускается, по-прежнему является открытым членом вашего класса. String .
Это означает, что в вашем примере должны запускаться два конструктора, но в целях обспецения оптимизации стандарт С++ разрешает опускать запуск конструктора копирования, так как, фактически, оба конструктора делают одну и ту же инициализациию создаваемого объекта, а потому излишне создание временного объекта, а затем с помощью него инициализировать ваш создаваемый объект. Но при этом конструктор копирования все равно должен быть доступен для вызова, иначе вы не сможете создать свой объект, так как формально должны вызываться два конструктора, как былло указано в начале.
Прикольно

Добавлено через 4 минуты
Только что попробовал в CodeGear Rad Studio C++ Builder , Поставил КОнструктор копии в приват секцию , нажал компилировать - ни 1 ошибки и варнинга:
C++
1
2
3
4
5
6
7
8
  private:
    strCount* psc;
    String(String& S)           // конструктор копирования
      {
        cout<<"String Konst Kopir"<<endl;
        psc = S.psc;
        (psc->count)++;
      }
silent_1991
Эксперт С++
4960 / 3036 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
01.02.2012, 09:04     запуск конструкторов #19
2e1553ce, билдер нельзя назвать строго соответствующим стандарту, и это ещё мягко сказано. Эталоном в данном случае является всё-таки g++, который действительно не компилирует изначальный код (и не скомпилирует приведённый выше, с закрытым конструктором копии), как я и говорил. Кстати, причину я назвал в сообщении 9 данной темы.
Сыроежка
Заблокирован
01.02.2012, 13:31     запуск конструкторов #20
Цитата Сообщение от 2e1553ce Посмотреть сообщение
Прикольно

Добавлено через 4 минуты
Только что попробовал в CodeGear Rad Studio C++ Builder , Поставил КОнструктор копии в приват секцию , нажал компилировать - ни 1 ошибки и варнинга:
C++
1
2
3
4
5
6
7
8
  private:
    strCount* psc;
    String(String& S)           // конструктор копирования
      {
        cout<<"String Konst Kopir"<<endl;
        psc = S.psc;
        (psc->count)++;
      }
Поздравляю! Вы только что обнаружили баг компилятора CodeGear Rad Studio C++ Builder!
Есть два варинта. Либо этот компилятор при оптимизации игнорирует закрытость конструктора копирования и остается довольным, что тот просто определен в одной из секций класса, либо вообще даже не обращает внимание на существование конструктора копирования. В любом случае это - баг.
Я бы вас попросил еще один эксперимент проделать, а именно не определять конструктор копирования, а только его объявить в закрытой секции. То есть будет так

C++
1
2
3
  private:
    strCount* psc;
    String(String& S);           // конструктор копирования
Если и это скомпилируется, то баг компилятора очень серьезный!
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.02.2012, 16:07     запуск конструкторов
Еще ссылки по теме:

Конфликт конструкторов. - C++
Здравствуйте! struct DateTime : tm { DateTime(int year_ = 1970, int month_ = 1, int day_ = 1,...

Наследование конструкторов? - C++
Сдаю лабораторную на тему наследования в С++ : #include &lt;iostream&gt; using namespace std; class hero { protected: int jiv; ...

Наследование конструкторов - C++
Здравствуйте! У меня такой вопрос: Как сделать так, чтобы при создании объекта дочернего класса не вызывался конструктор родительского? При...

Виды конструкторов - C++
Какие конструкторы существуют в С++? Инфу с вики читал, но почему то все равно ответ не верен. Варианты ответа: 1) Копирования ...

Перегрузка конструкторов - C++
Написал прогу - в зависимости от ввода даты печатает ее в определенном формате: файл date.h #ifndef DATE1_H #define DATE1_H class...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
2e1553ce
1 / 1 / 1
Регистрация: 16.12.2011
Сообщений: 47
01.02.2012, 16:07  [ТС]     запуск конструкторов #21
Компилирует :O
Yandex
Объявления
01.02.2012, 16:07     запуск конструкторов
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru