Форум программистов, компьютерный форум, киберфорум
Наши страницы

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

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

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

30.01.2012, 11:16. Просмотров 1740. Ответов 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 конструктора ?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.01.2012, 11:16
Здравствуйте! Я подобрал для вас темы с ответами на вопрос запуск конструкторов (C++):

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

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

Наследование конструкторов - C++
Здрасти. Такая проблема. У меня есть классы с таким наследованием: KIERUNEK-->PRZEDMIOT-->OCENA<--STUDENT Вот конструкторы класса...

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

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

Наследование конструкторов - C++
Создать класс CPoint – точка. На его основе создать классы CColoredPoint и CLine. На основе класса СLine создать класс CcoloredLine и класс...

20
Chelioss
180 / 180 / 4
Регистрация: 08.01.2011
Сообщений: 1,133
31.01.2012, 19:20 #16
Цитата Сообщение от OstapBender Посмотреть сообщение
кстати только вчера видел пример вызова из 1го конструктора - другого
Я вообще-то не про это.
0
Сыроежка
Заблокирован
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 .
Это означает, что в вашем примере должны запускаться два конструктора, но в целях обспецения оптимизации стандарт С++ разрешает опускать запуск конструктора копирования, так как, фактически, оба конструктора делают одну и ту же инициализациию создаваемого объекта, а потому излишне создание временного объекта, а затем с помощью него инициализировать ваш создаваемый объект. Но при этом конструктор копирования все равно должен быть доступен для вызова, иначе вы не сможете создать свой объект, так как формально должны вызываться два конструктора, как былло указано в начале.
2
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)++;
      }
0
silent_1991
Эксперт С++
4989 / 3046 / 149
Регистрация: 11.11.2009
Сообщений: 7,028
Завершенные тесты: 1
01.02.2012, 09:04 #19
2e1553ce, билдер нельзя назвать строго соответствующим стандарту, и это ещё мягко сказано. Эталоном в данном случае является всё-таки g++, который действительно не компилирует изначальный код (и не скомпилирует приведённый выше, с закрытым конструктором копии), как я и говорил. Кстати, причину я назвал в сообщении 9 данной темы.
0
Сыроежка
Заблокирован
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);           // конструктор копирования
Если и это скомпилируется, то баг компилятора очень серьезный!
0
2e1553ce
1 / 1 / 1
Регистрация: 16.12.2011
Сообщений: 47
01.02.2012, 16:07  [ТС] #21
Компилирует :O
0
01.02.2012, 16:07
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.02.2012, 16:07
Привет! Вот еще темы с ответами:

вызовы конструкторов - C++
обьясните вызов конструторов #include &lt;iostream&gt; using namespace std; class ar { int *p; int size; public:

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

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

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


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

Или воспользуйтесь поиском по форуму:
21
Ответ Создать тему
Опции темы

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