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

Никогда не использовать конструктор с параметрами? - C++

Восстановить пароль Регистрация
 
 
nefton
44 / 20 / 5
Регистрация: 28.02.2013
Сообщений: 184
05.03.2013, 10:52     Никогда не использовать конструктор с параметрами? #1
Если я захочу чтоб в одном классе был вложен другой класс

Не по теме:

например есть класс "бумажник"
а класс "человек" среди своих данных содержит экземпляр класса "бумажник"


То обнаружу что я не могу передать его конструктору параметры.
а могу лишь написать:
C++
1
2
3
4
5
6
class c_Chelovek {
 
public:
    c_Chelovek();
    c_Bumaznik bumaznik;
}
При этом вызовется именно конструктор c_Bumaznik() без параметров.

Если же я захочу написать функцию типа c_Chelovek::AddBumaznik(int dengi);
и в ней вызвать конструктор бумажника с параметрами - то ничего ни выходит.
Типа обьект уже создан.

Отсюда делаю далеко идущие выводы.
Вот пишу я класс. Возможно когда то я или кто то захочет использовать его экземпляр внутри своего класса.
тогда у меня один правильный выход:
-писать конструктор без параметров
-писать функцию класса Init(params); //Функцию инициализации класса с параметрами

Я чтото упустил из виду?

Добавлено через 12 минут
Или же так не делают. А надо по хитрому.
- заводить переменную - указатель на обьект "бумажник"
- в функции c_Chelovek::AddBumaznik(int dengi) выделять оператором new новый экземпляр класса "бумажник"
при этом ему можно сообщать параметры конструктора
и в переменную(указатель) писать адресс вновь созданого обьекта
и с ним потом както работать
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11828 / 6807 / 769
Регистрация: 27.09.2012
Сообщений: 16,878
Записей в блоге: 2
Завершенные тесты: 1
05.03.2013, 10:56     Никогда не использовать конструктор с параметрами? #2
Цитата Сообщение от nefton Посмотреть сообщение
Я чтото упустил из виду?
Список инициализации?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
class B{
    int x;
public:
    B();
    B(int _x){x=_x;}
    int GetX(){return x;}
};
class A{
    B b_obj;
public:
    A():b_obj(12){};//!!!
    A(int x):b_obj(x){};//!!!
    int GetX(){return b_obj.GetX();}
};
 
int main(){
    A a1;
    A a2(25);
    std::cout<<a1.GetX()<<std::endl;
    std::cout<<a2.GetX()<<std::endl;
}
CheshireCat
Эксперт С++
2907 / 1235 / 78
Регистрация: 27.05.2008
Сообщений: 3,307
05.03.2013, 10:57     Никогда не использовать конструктор с параметрами? #3
Упустил.

Не по теме:

Мне кажется довольно нелепой ситуация, когда Человек "рождается" уже с Бумажником... :-) Но не буду обсуждать концепцию.



Решений есть несколько:
1. Конструктор по умолчанию класса Человек может либо инициализировать Бумажник некоторой суммой денег по умолчанию, либо создавать пустой Бумажник. В последнем случае, классу Человек целесообразно иметь метод ДобавитьДенегВБумажник(сумма) - обрати внимание, не ДобавитьНовыйБумажник!
2. Класс Человек может иметь несколько Бумажников (вектор Бумажников). И добавлять/удалять Бумажники по потребности.
3. Наконец, класс Человек может иметь указатель на Бумажник. Этот указатель по умолчанию может указывать в NULL - т.е. по умолчанию Человек нищий :-) А затем Человек может присваивать себе указатели на чужие Бумажники, в том числе - и не один :-)))

В общем, пиши тестовый код.... поглядим. Сложного-то ничего нет. Просто нужно прежде всего правильно сформулировать, какого именно поведения своих классов ты хочешь добиться.
nefton
44 / 20 / 5
Регистрация: 28.02.2013
Сообщений: 184
05.03.2013, 10:58  [ТС]     Никогда не использовать конструктор с параметрами? #4
если у меня класс A содержит 'экземпляры классов B и С и D?
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11828 / 6807 / 769
Регистрация: 27.09.2012
Сообщений: 16,878
Записей в блоге: 2
Завершенные тесты: 1
05.03.2013, 11:00     Никогда не использовать конструктор с параметрами? #5
Цитата Сообщение от nefton Посмотреть сообщение
Типа обьект уже создан.
Все правильно. конструктор вызывается при создании объекта.
Если Вам нужно менять состояние объекта, то делайте соответствующие функции-члены класса
ITcrusader
Эксперт C++
 Аватар для ITcrusader
176 / 162 / 8
Регистрация: 12.02.2013
Сообщений: 410
05.03.2013, 11:01     Никогда не использовать конструктор с параметрами? #6
Упустил.

Моделирование человека со вложенным бумажником - не вполне корректно, это раз. Отсюда твоя проблема.
Вложенные класса создаются в порядке их объявления внутри класса, а значит их конструктор вызывается при создании класса, их содержащего. Конструктор ты явно вызвать не можешь, потому у тебя следующие варианты:
1. сделать для бумажника конструктор с параметром и создавать человека, указывая для него, сколько у него денег (посредством передачи конструктору человека нужной цифры и дальнейшей её передачи конструктору с параметром бумажника.)
2. создавать человека с пустым бумажником, и завести функцию, которая будет (наделять его лавэ)

3. изменить модель.

Впрочем, вполне нормальная ситуация, когда ты создаешь человека с пустым бумажником и делаешь для него функу, например, положить в бумажник n лавэ. Это вполне отражает реальную ситуацию. Конструктор же по умолчанию для бумажника, который содержит, полагаю, какое-то поле, логично было бы написать и инициализировать это поле нулём.

Но повторяю, твоя модель подразумевает, что у каждого человека обязательно есть бумажник, как неотъемлемый атрибут. Если в контексте решаемой задачи это нормально, тока в путь

Ответы на далеко идущие выводы.
Ну вообще, когда ты пишешь класс, ты обязан реализовать в нем интерфейс самодостаточный для использования его тобой/кем бы то ни было. Потому да, как бы ни был создан экземпляр, он должен быть инициализирован нормальными значениями и работоспособен.

Другое дело, что едва ли твой кошелек может сам себя наполнять n-й суммой)))

И конечно, твой класс должен предоставлять (как правило) set-, get-методы для пользователей. Надеюсь, нужное написал, если чо, спрашивай.

Пока катал - стока ответов уже)))))
nefton
44 / 20 / 5
Регистрация: 28.02.2013
Сообщений: 184
05.03.2013, 11:39  [ТС]     Никогда не использовать конструктор с параметрами? #7
Вот в том то и дело. Я пишу класс "бумажник".
- я не знаю кто и как захочет потом этот класс использовать
- я пишу чтото в надежде написать.
Тоесть надеюсь что написав один раз файлы bumaznik.h и bumaznik.cpp
никогда не открою bumaznik.cpp даже для чтения
и просто включу bumaznik.h инклудом в файл где буду использовать этот класс
- я не хочу писать лишний код (это как минимум не логично)
Тогда у меня 2 выбора:
- делать конструктор без параметров и функцию Init(params) (В часном случае ДобавитьДеньги(деньги) )
- заставить програмиста работать через указатели с моим классом в случае если он захочет его включить в свой

Добавлено через 1 минуту
ладно, параметр деньги неудачный пример. Давайте использовать параметр "цвет"
бумажник же рождается с цветом

Добавлено через 1 минуту
И человек не рождается с бумажником, но у него ведь может быть функция ПошитьСебеБумажник(цвет) типа такого

Добавлено через 23 минуты
Впрочем если принять за аксиому что
Работать не с обьектами а с сылками на них - это просто и естественно
то никаких противоречий нет в использовании конструкторов с параметрами.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11828 / 6807 / 769
Регистрация: 27.09.2012
Сообщений: 16,878
Записей в блоге: 2
Завершенные тесты: 1
05.03.2013, 11:46     Никогда не использовать конструктор с параметрами? #8
Цитата Сообщение от nefton Посмотреть сообщение
делать конструктор без параметров и функцию Init(params) (В часном случае ДобавитьДеньги(деньги) )
заставить програмиста работать через указатели с моим классом в случае если он захочет его включить в свой
ЗАЧЕМ???
Вы вообще понимаете зачем нужен конструктор или нет???
Если кому-то нужно будет создать объект с параметрами не по умолчанию - создадут с вызовом соответствующего конструктора, если он конечно есть.
CheshireCat
Эксперт С++
2907 / 1235 / 78
Регистрация: 27.05.2008
Сообщений: 3,307
05.03.2013, 11:56     Никогда не использовать конструктор с параметрами? #9
nefton, начни с простой штуки: опиши назначение твоего класса-Бумажника и основные сценарии использования (use cases) этого Бумажника. Отсюда будет ясен интерфейс твоего класса-Бумажника.

А то пока ты конструируешь сферический Бумажник в вакууме :-)
nefton
44 / 20 / 5
Регистрация: 28.02.2013
Сообщений: 184
05.03.2013, 12:15  [ТС]     Никогда не использовать конструктор с параметрами? #10
Код
класс бумажник {
конструктор бумажник(цвет);
void ВзятьДеньги(деньги);
void ПоложитьДеньги(деньги);
цвет ПосмотретьЦвет();
}

класс Человек {
конструктор Человек(рост, вес);
void СделатьСебеБумажник(цвет);
цвет ПосмотретьЦветБумажника();
бумажник мой_бумажник;
//либо бумажник* мой_указатель_на_бумажник;
}

Человек::СделатьСебеБумажник(цвет){
//невозможно!
//Хотя вроде класс бумажник вполне логичен и самодостаточен... был
//идём дописывать в бумажник конструктор по умолчанию и странную функцию ДобавитьЦвет(цвет) 
}


// вариант если мы обьявили мой_указатель_на_бумажник
Человек::СделатьСебеБумажник(цвет){ 
мой_указатель_на_бумажник = new бумажник(цвет);
}

цвет Человек::ПосмотретьЦветБумажника(){
return мой_указатель_на_бумажник->ПосмотретьЦвет();
}
вся проблема в том что для меня как обычного человека естественнее использовать в программе бумажник, а не указатель на него
Но походу надо привыкать что переменная мой_указатель_на_бумажник - это нормально
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
05.03.2013, 12:20     Никогда не использовать конструктор с параметрами? #11
Цитата Сообщение от nefton Посмотреть сообщение
класс Человек {
конструктор Человек(рост, вес);
void СделатьСебеБумажник(цвет);
цвет ПосмотретьЦветБумажника();
бумажник мой_бумажник;
//либо бумажник* мой_указатель_на_бумажник;
}
Человек::СделатьСебеБумажник(цвет){
//невозможно!
//Хотя вроде класс бумажник вполне логичен и самодостаточен... был
//идём дописывать в бумажник конструктор по умолчанию и странную функцию ДобавитьЦвет(цвет)
}
C++
1
2
3
4
Человек::СделатьСебеБумажник(цвет){
мой_бумажник=бумажник(цвет);
//либо delete  мой_указатель_на_бумажник; мой_указатель_на_бумажник=new бумажник;
}
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
05.03.2013, 12:34     Никогда не использовать конструктор с параметрами? #12
Кривовато, но хотя бы логично.

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
class human;
class wallet_factory;
 
namespace wallet_space
{
 
class impl
{
public:
    // бумажник еще не имеет владельца (лежит в магазине например)
    impl() : owner(nullptr) { }
    // функции
private:
   friend class wallet_factory;
   impl(human* own) : owner(own) { }
   human* owner;
};
 
}
 
typedef std::shared_ptr<wallet_space::impl> wallet;
 
class wallet_factory
{
public:
    static wallet create(Human& h)
    {
        return wallet(new wallet_space::impl(&h));
    }
};
 
int main()
{
   Human h;
   // Human h owns wallet wal.
   wallet wal = wallet_factory::create(h);
}
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
05.03.2013, 12:36     Никогда не использовать конструктор с параметрами? #13
ForEveR, зачем в бумажнике хранить human* owner;
?
CheshireCat
Эксперт С++
2907 / 1235 / 78
Регистрация: 27.05.2008
Сообщений: 3,307
05.03.2013, 12:37     Никогда не использовать конструктор с параметрами? #14
nefton, весь описанный тобою интерфейс легко конструируется:
(код сильно упрощенный, но собирается)
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
class Wallet
{
    int c;
public:
    Wallet(int color) {};
    void MoneyOut(int sum) {};
    void MoneyIn(int sum) {};
    int Color()
    {
        return c;
    };
};
 
class Human
{
    Wallet w;
public:
    // бумажник должен иметь какой-то цвет по умолчанию:
    Human(int growth, int weight): w(0) {};
 
    void MakeWallet(int color);
    int GetWalletColor();
};
 
void Human::MakeWallet(int color)
{
    Wallet newWallet(color);
// здесь можно переложить в новый бумажник деньги из старого....
    w = newWallet;
}
 
 
int Human::GetWalletColor()
{
    return w.Color();
}
 
int main()
{
    Human h(180, 65);
    h.MakeWallet(1);  // новый бумажник другого цвета
    int i = h.GetWalletColor();
}
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11828 / 6807 / 769
Регистрация: 27.09.2012
Сообщений: 16,878
Записей в блоге: 2
Завершенные тесты: 1
05.03.2013, 12:41     Никогда не использовать конструктор с параметрами? #15
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
зачем в бумажнике хранить human* owner;
а чтобы найти свой, когда потеряет
nefton
44 / 20 / 5
Регистрация: 28.02.2013
Сообщений: 184
05.03.2013, 12:44  [ТС]     Никогда не использовать конструктор с параметрами? #16
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
#include <iostream>
using namespace std;
 
class bumaznik {
public:
    bumaznik(int color){bumaznik::color=color;};
    int GetColor(){return color;};
    int color;
};
class chelovek {
public:
    chelovek(int rost){chelovek::rost=rost;};
    void MakeBumaznik(int color);
    bumaznik my_bumaznik;
    int rost;
};
 
void chelovek::MakeBumaznik(int color){
    my_bumaznik=bumaznik(color);
}
 
 
 
void main(){
 
    chelovek Vasiliy(180);
    Vasiliy.MakeBumaznik(5);
 
    cout<<Vasiliy.my_bumaznik.GetColor();
 
    int g;
    cin>>g;
 
}
Некатит пишет ошибка
error C2512: 'bumaznik' : no appropriate default constructor available
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
05.03.2013, 12:47     Никогда не использовать конструктор с параметрами? #17
Цитата Сообщение от nefton Посмотреть сообщение
chelovek(int rost){chelovek::rost=rost;};
C++
1
chelovek(int rost): my_bumaznik(0){chelovek::rost=rost;}
nefton
44 / 20 / 5
Регистрация: 28.02.2013
Сообщений: 184
05.03.2013, 12:47  [ТС]     Никогда не использовать конструктор с параметрами? #18
Цитата Сообщение от CheshireCat Посмотреть сообщение
// бумажник должен иметь какой-то цвет по умолчанию:
* * Human(int growth, int weight): w(0) {};
разве? спроси у прохожего какой цвет его бумажника по умолчанию

Да и во что превратится конструктор человека если у него не только бумажник, а и блокнот, портфель, карманы, и ещё пол сотни обьектов
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
05.03.2013, 12:51     Никогда не использовать конструктор с параметрами? #19
Цитата Сообщение от nefton Посмотреть сообщение
разве? спроси у прохожего какой цвет его бумажника по умолчанию
бред. Просто скажи, что ты хочешь от человека? Чтобы он принимал в своём конструкторе цвет бумажника или, чтобы его бумажник по умолчанию имел color=0 ???
Третьего не дано. Всё потому, что его бумажник всегда создаётся одновременно с человеком.
Ты не можешь создать бумажник без цвета. + бумажник создаётся в процессе создания человека = ты обязан определиться с цветом в процессе создания человека
И тем самым, кстати, С++ оберегает тебя от ошибок.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.03.2013, 12:55     Никогда не использовать конструктор с параметрами?
Еще ссылки по теме:

C++ Пример класса с конструктором и деструктором, создание экземпляра класса через конструктор с параметрами
Как вызвать конструктор с параметрами в конструкторе без параметров? C++
Конструктор с параметрами C++

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

Или воспользуйтесь поиском по форуму:
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
05.03.2013, 12:55     Никогда не использовать конструктор с параметрами? #20
nefton, Ну во-первых если и хранить в классе человека какие-то объекты, то либо быть уверенным, что человек обязан обладать этими объектами, либо хранить указатели. Либо хранить указатель/ссылку на человека в конкретном типе. Либо построить взаимодействие несколько по-другому, например через id-шники, а связь устроить через БД.
Yandex
Объявления
05.03.2013, 12:55     Никогда не использовать конструктор с параметрами?
Ответ Создать тему
Опции темы

Текущее время: 00:55. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru