Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/15: Рейтинг темы: голосов - 15, средняя оценка - 4.60
0 / 0 / 1
Регистрация: 05.09.2014
Сообщений: 96

Зачем в программе 2 раза вызывать конструктор для одного объекта

19.02.2015, 10:17. Показов 3101. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, специалисты!
Попалась в руки программа, похожая на то что мне надо сделать, начал разбираться и недоумеваю - зачем два раза вызывается конструктор для одного и того же объекта???
Вывожу на печать - вместо трех создается и удаляется 6 объектов!!!
В чем логика?
И обязательно ли использовать статическую функцию Polar или нет? Зачем указано inline?

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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <stdlib.h>
#include <math.h>
#include <iostream.h>
 
class P {
 private:  
    float x;
    float y;
    P(float  X, float Y) : x(X), y(Y) {printf ("1\n"); };
public:
    float getx() { return x; };  
    float gety() { return y; };  
static P Polar(float, float); 
    P() { x=y=0.0; printf ("2\n");};
   ~P();  
  };
 
inline P P::Polar(float R, float F) {  
  P p(R*cos(F), R*sin(F));
  return p;
}
 
P::~P(void)
{ 
   printf ("3\n"); 
}
 
// основная функция
int main(int argc, char* argv[ ]) {
float edge = 1.0;                          
float angle = 0.0;                        
float pi = acos (-1.0 );
float radius;
int i = 0;
P vertex [3];                 
  if(argc > 1)  
    edge = atof (argv[1]);
    cout << "pi=" << pi << endl;
    radius = edge / (2*sin(pi/3.0));
while (i<3) {
     vertex[ i ] = P::Polar(radius, angle); 
     angle += ((2.0*pi)/3.0);
     i++;
    }
do  { 
  --i; 
  cout << vertex[ i ].getx() << ';' <<  vertex[ i ].gety() << endl;
 } while(i > 0);
  return (0);
}// main
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
19.02.2015, 10:17
Ответы с готовыми решениями:

Конструктор для помещения одного объекта в создаваемый объект
class NewThread implements Runnable { Thread t; NewThread() { // Создать новый, второй поток t = new Thread(this,...

Зачем нужен конструктор объекта ostringstream (строковый поток который) с двумя аргументами?
От него всё равно толку как от быка молока. А вроде как предназначен для записи чего-то там в строку... #include &lt;string&gt; ...

Unity не хочет вызывать скрипты для объекта
Юнити не хочет вызывать скрипты для объекта.Некоторые видит некоторые нет.Я не могу,к примеру,сделать скрипт,кторый делает вращение.Я...

10
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
19.02.2015, 10:44
В 35-й строке 3 раза и в 41-й (19-й) тоже три.
Там показывает 1 3 3, т. е. создан новый в 19-й строке, затем удалён из vertex, затем скопирован и удалён возвращённый функцией.
0
0 / 0 / 1
Регистрация: 05.09.2014
Сообщений: 96
19.02.2015, 11:40  [ТС]
Не совсем понял ответ - так и должно быть? Зачем создавать объекты чтобы их потом удалять, копировать и прочее? Не лучше ли один раз создать, а затем функцией заполнить поля? Зачем внутри функции вызывать конструктор?
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
19.02.2015, 12:27
Цитата Сообщение от студ Посмотреть сообщение
Попалась в руки программа, похожая на то что мне надо сделать, начал разбираться и недоумеваю - зачем два раза вызывается конструктор для одного и того же объекта???
Так велели голоса в голове разработчиков C++. В C++11 можно написать P vertex[3]={{1,2},{3,4},{5,6}} и радоваться.
Цитата Сообщение от студ Посмотреть сообщение
И обязательно ли использовать статическую функцию Polar или нет?
C++ не позволяет создать два конструктора с одинаковым набором переменных (ага, опять голоса). Поэтому если хотите без Polar, надо прикручивать к конструктору третий аргумент format, указывающий декартовы у вас координаты или полярные. Сам аргумент можно потом игнорировать. Просто если он есть - вызывается один конструктор, ну а если нет - другой.
0
0 / 0 / 1
Регистрация: 05.09.2014
Сообщений: 96
19.02.2015, 12:52  [ТС]
Проблема в том, что начал пробовать переписать без второго конструктора, то есть конструктором по умолчанию создаю массив объектов, затем в мейне просто пытался присвоить переменным х и у элементов массива нужные значения - ругается, говорит невозможно присвоить значения несуществующим объектам... а как они не существуют если я их создал уже? Код не выкладываю так как уже все переделал обратно...
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
19.02.2015, 12:55
Цитата Сообщение от студ Посмотреть сообщение
затем в мейне просто пытался присвоить переменным х и у элементов массива нужные значения - ругается, говорит невозможно присвоить значения несуществующим объектам...
x и y объявлены как приватные поля. Это собственно и означает что до них никто кроме класса достучаться не может.
0
0 / 0 / 1
Регистрация: 05.09.2014
Сообщений: 96
19.02.2015, 18:49  [ТС]
Да, дела имено через методы класса - то есть создал в классе метод в публичной области и его вызывал для инициализации значений.

Добавлено через 5 часов 45 минут
Вопрос остается открытым - правильно ли так делать или это противоречит логике ООП?
0
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,871
19.02.2015, 19:07
Лучший ответ Сообщение было отмечено студ как решение

Решение

Цитата Сообщение от студ Посмотреть сообщение
vertex[ i ] = P::Polar(radius, angle);
вот здесь создается временный объект
загляни в функцию Polar
он создался скопировался и удалился
все это делается для заполнения полей объекта, ибо функции запонения нет
и конструктор с параметрами приватный т.е нельзя написать что то типа
C++
1
vertex[ i ] = P(radius, angle);
ибо конструктор с параметрами приватный
хотя здесь также бы создавался временный объект

и так нельзя
C++
1
vertex[ i ].Set(radius, angle);
нет функции Set
Цитата Сообщение от студ Посмотреть сообщение
правильно ли так делать или это противоречит логике ООП
нисколько не противоречит, так захотел автор
а вот если бы писал так
C++
1
vertex[ i ].X=radius*cos(angle);
то противоречило бы
нельзя стучатся к членам класса напрямую
1
0 / 0 / 1
Регистрация: 05.09.2014
Сообщений: 96
19.02.2015, 19:14  [ТС]
Спасибо за подробные объяснения! Не могли бы еще уточнить:

Цитата Сообщение от ValeryS Посмотреть сообщение
вот здесь создается временный объект
загляни в функцию Polar
А где видно что объект временный?

Цитата Сообщение от ValeryS Посмотреть сообщение
а вот если бы писал так
Код C++
1
vertex[ i ].X=radius*cos(angle);
то противоречило бы
нельзя стучатся к членам класса напрямую
Это потому что они приватные? Но ведь можно создать функцию класса для заполнения?
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
19.02.2015, 19:23
Лучший ответ Сообщение было отмечено студ как решение

Решение

Цитата Сообщение от студ Посмотреть сообщение
Но ведь можно создать функцию класса для заполнения?
Можно.
Цитата Сообщение от студ Посмотреть сообщение
А где видно что объект временный?
Если некое выражение (в данном случае вызов функции) возвращает объект по значению, то это значение всегда временное. Если компилятор не применит никаких оптимизаций, то будет так:
1) Создание объекта внутри функции
2) Возврат объекта из функции по значению, это копия объекта из пункта 1 (эта копия - временный объект).
3) Уничтожение объекта из пункта 1.
4) Присвоение временного объекта i-му элементу в массиве.
5) Уничтожение временного объекта в конце выражения.
Такие вещи часто оптимизируются, см. RVO, NRVO. Но по смыслу происходит именно это.
1
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,871
19.02.2015, 19:44
Цитата Сообщение от студ Посмотреть сообщение
Это потому что они приватные?
в данном случае да
но нет
если ты сделаешь их Публиком то менять сможешь, но здесь уже нарушаешь ООП

свойства объекта может менять только объект
один из китов ООП
В шарпе на каждый член создается Set Get
представь что все кто не лень может менять члены
вот у тебя есть класс человек у него есть член(у класса, не у человека) возраст и кто то со стороны написал -100 лет и объект будет существовать с таким идиотским возрастом
а если ты напишешь член приватным и опишешь метод заполнения то такое можешь избежать
типа
C++
1
2
3
4
5
void Man::SetAge(int a)
{
  if(a>-1 && a<120)
   age=a;
}
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
19.02.2015, 19:44
Помогаю со студенческими работами здесь

Как правильно вызывать функцию объекта из другой функции того же объекта?
Доброго дня и ночи, уважаемые программисты! Существует некоторая проблема, на которую я наткнулся, решая задачу по программированию из...

Свойство объекта в виде массива char заполняется только для одного объекта
Есть два свойства: одно - string, второе - массив char. Если начать заполнять их двум и более объектам, то char заполняется только для...

Писать несколько обработчиков для одного события или один обработчик, в котором вызывать методы?
Например есть событие Click. Для него автоматически создается обработчик button_Click (object sender, EventArgs e) Мне нужно...

Зачем вызывать Dispose(), если в итоге вызовется Finalize()?
При использовании классов,работающих с системными ресурсами,желательно (обязательно?) создавать их с помощью using. Компилятор создаст...

this(Всегда ли вызывается конструктор при не явной передачи объекта в конструктор)
class Test { int i; public: void test(int i) { this -&gt; i = i; } }; Конструктор Test::Test всегда вызывается...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru