Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вызов метода в конструкторе 
:(
    Опции темы
Sergio
  Дата 16.3.2009, 22:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 843
Регистрация: 28.7.2006
Где: Solar System-> Earth

Репутация: нет
Всего: 1



Всем привет. Есть класс:
Код

class C
{
public:
    C::C() { this->Show(); };
    C::~C() { printf("A::Destructor()\n"); };
    void Show() { printf("A::Show()\n"); }
};

...

C *obj = new C();

При создании объекта в консоль напишет "A::Show()". 
Вопросы:
Правильный ли это подход ООП? Я считаю что не рекомендуеться вызывать методы своего же класса. Поскольку метод может быть "завязан" на переменные которые ещё не инициализировались? 
Какие методы нельзья вызывать в конструкторе/деструкторе ?

Спасибо.
PM MAIL ICQ   Вверх
Anikmar
Дата 16.3.2009, 22:36 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 5
Всего: 59



ИМХО
В конструкторе вообще лучше ничего не вызывать. Особенно методы, которые могут привести к исключениям.
Лично я конструктор использую только для начальной инициализации переменных. Даже new стараюсь не использовать - опять таки ИМХО.
PM MAIL ICQ   Вверх
Lazin
Дата 16.3.2009, 22:45 (ссылка) |    (голосов:6) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 27
Всего: 154



Цитата(Sergio @  16.3.2009,  22:33 Найти цитируемый пост)
Правильный ли это подход ООП? Я считаю что не рекомендуеться вызывать методы своего же класса. Поскольку метод может быть "завязан" на переменные которые ещё не инициализировались?

во время выполнения тела конструктора объект уже создан и все переменные объекта инициализированы

Цитата(Sergio @  16.3.2009,  22:33 Найти цитируемый пост)
Какие методы нельзья вызывать в конструкторе/деструкторе ?

виртуальные
PM MAIL Skype GTalk   Вверх
Anikmar
Дата 16.3.2009, 23:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 5
Всего: 59



Цитата(Lazin @  16.3.2009,  22:45 Найти цитируемый пост)
во время выполнения тела конструктора объект уже создан и все переменные объекта инициализированы

Дополню.
Однако переменные, которые указывают на некие объекты, которые еще должны быть созданы пока еще содержат NULL. 
PM MAIL ICQ   Вверх
mes
Дата 17.3.2009, 00:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(Anikmar @  16.3.2009,  22:08 Найти цитируемый пост)
Однако переменные, которые указывают на некие объекты, которые еще должны быть созданы пока еще содержат NULL.  

NULL - eсли об этом "не забыл" позаботиться разработчик smile

Добавлено через 1 минуту и 54 секунды
я думаю, тс, стоит прочитать о том как все это происходит в книжке, потому что по высказанному из за не подготовки можно составить ложную картину.


--------------------
PM MAIL WWW   Вверх
math64
Дата 17.3.2009, 08:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



Код

class A {
public:
A() { Show(); }
virtual Show() { printf("A\n"); }
};
class B : public A{
B() : A() {}
virtual Show() { printf("B\n"); }
};
void main() {
A* a = new B();
}

выведет A
Но если программируете на C++Builder и
Код

class A : public TObject {

то выведет B
Аналочично при вызове виртуальных методов в деструкторе.
PM   Вверх
Albor
Дата 17.3.2009, 10:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 589
Регистрация: 28.2.2009

Репутация: 2
Всего: 9



Цитата(Sergio @  16.3.2009,  21:33 Найти цитируемый пост)
Правильный ли это подход ООП? Я считаю что не рекомендуеться вызывать методы своего же класса. Поскольку метод может быть "завязан" на переменные которые ещё не инициализировались?

Так сначала инициализируй, а потом вызывай метод. Можно и так проинициализировать
Код

A(): MyVar var1=какое-то значение
{
   Show();



PM MAIL ICQ   Вверх
azesmcar
Дата 17.3.2009, 10:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Цитата

A(): MyVar var1=какое-то значение
{
   Show();


 smile какой-то странный метод инициализации, может все таки так?
Код

A(): MyVar(var1)
{
   Show();


PM   Вверх
mes
Дата 17.3.2009, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(azesmcar @  17.3.2009,  09:54 Найти цитируемый пост)

 smile какой-то странный метод инициализации, может все таки так?
Код

A(): MyVar(var1)

или так A(MyVar var) : m_var(var) {}
так как MyVar в
Цитата(Albor @  17.3.2009,  09:26 Найти цитируемый пост)
A(): MyVar var1=какое-то значение

 больше напоминает тип.
 smile 

Это сообщение отредактировал(а) mes - 17.3.2009, 12:51


--------------------
PM MAIL WWW   Вверх
Albor
Дата 17.3.2009, 12:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 589
Регистрация: 28.2.2009

Репутация: 2
Всего: 9



Цитата(azesmcar @  17.3.2009,  09:54 Найти цитируемый пост)
  какой-то странный метод инициализации, может все таки так?

Ну, да, скосячил! Мне стыдно! Нужно было вызывать конструктор var1(значение)


Это сообщение отредактировал(а) Albor - 17.3.2009, 13:03
PM MAIL ICQ   Вверх
Vyacheslav
Дата 19.3.2009, 13:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: нет
Всего: 59



Цитата(Lazin @  16.3.2009,  22:45 Найти цитируемый пост)
Цитата(Sergio @  16.3.2009,  22:33 Найти цитируемый пост)
Какие методы нельзья вызывать в конструкторе/деструкторе ?

виртуальные

Ни кто не запрещает вызывать виртуальные методу в конструкторе, так как поведение в этом случае четко определено стандартом.


--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
vinter
Дата 19.3.2009, 14:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 8
Всего: 56



вот кстати хотел ответить Лазину -  как говорит Вячеслав:"использовать можно, если понимать как они себя поведут"  smile 


--------------------
Мой блог
PM MAIL WWW   Вверх
mes
Дата 19.3.2009, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(Vyacheslav @  19.3.2009,  12:49 Найти цитируемый пост)
Цитата(Lazin @  16.3.2009,  22:45 Найти цитируемый пост)
Цитата(Sergio @  16.3.2009,  22:33 Найти цитируемый пост)
Какие методы нельзья вызывать в конструкторе/деструкторе ?

виртуальные

Ни кто не запрещает вызывать виртуальные методу в конструкторе, так как поведение в этом случае четко определено стандартом.
У нельзя есть два значения : запрещено и невозможно. В вопросе мне кажется подразумевается последнее. smile
глагол конечно лучше было в таком случае использовать "вызвать", а не "вызывать" - но это можно отнести на (плохое) качество перевода.

Это сообщение отредактировал(а) mes - 19.3.2009, 15:13


--------------------
PM MAIL WWW   Вверх
lv151
Дата 19.3.2009, 15:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 916
Регистрация: 11.2.2008

Репутация: нет
Всего: 2



Цитата(Lazin @  16.3.2009,  22:45 Найти цитируемый пост)
во время выполнения тела конструктора объект уже создан и все переменные объекта инициализированы

Можно узнать источник этой информации?
PM MAIL   Вверх
azesmcar
Дата 19.3.2009, 15:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Цитата

Можно узнать источник этой информации? 


C++ Standard
PM   Вверх
lv151
Дата 19.3.2009, 16:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 916
Регистрация: 11.2.2008

Репутация: нет
Всего: 2



У Шилдта  - "Конструктор автоматически вызывается в момент создания объекта т.е. при его объявлении."
PM MAIL   Вверх
zim22
Дата 19.3.2009, 16:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



lv151, правильно. при объявлении объекта. но при объявлении класса.


--------------------
PM MAIL   Вверх
azesmcar
Дата 19.3.2009, 16:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Цитата

У Шилдта  - "Конструктор автоматически вызывается в момент создания объекта т.е. при его объявлении." 


и...?
Код

MyClass::MyClass(int var) : var_(var) //инициализация проиходит тут
{
   //тут уже все инициализировано, то что не описано в списке инициализации - инициализируется по умолчанию (если это возможно)
}


чем одно мешает другому?
PM   Вверх
lv151
Дата 19.3.2009, 16:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 916
Регистрация: 11.2.2008

Репутация: нет
Всего: 2



Я запутался smile. Можете "на пальцах" объяснить?

Добавлено @ 16:05
Цитата(azesmcar @  19.3.2009,  16:02 Найти цитируемый пост)
MyClass::MyClass(int var) : var_(var)

Всё ясно, был невнимателен.

Думал что:
Код

MyClass::MyClass()
{
   //тут уже все инициализировано, то что не описано в списке инициализации - инициализируется по умолчанию (если это возможно)
}


Это сообщение отредактировал(а) lv151 - 19.3.2009, 16:31
PM MAIL   Вверх
azesmcar
Дата 19.3.2009, 16:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Цитата

Я запутался smile. Можете "на пальцах" объяснить? 


Код

int i = 1; //это инициализация
int p; //неинициализированная переменная
int p = int(); //это инициализация по умолчанию


Код

MyClass::MyClass(int var)
   : var_(var) //это тоже
{

}

если создать обьект как
Код

MyClass v = MyClass(); //все члены явно не инициализированые в member initialization list инициализируются по умолчанию
MyClass v; //те члены класса которые явно не инициализированы в member initialization list останутся неинициализированными
                 //но  нормально созданными и готовыми к работе). Т.е. можно им присваивать и тому подобное..
                 //т.е. если что-то и неинициализировано, то о вашей вине.



Это сообщение отредактировал(а) azesmcar - 19.3.2009, 16:12
PM   Вверх
vinter
Дата 19.3.2009, 16:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 8
Всего: 56



Цитата(azesmcar @  19.3.2009,  17:11 Найти цитируемый пост)
MyClass v = MyClass(); //все члены явно не инициализированые в member initialization list инициализируются по умолчанию
MyClass v; //те члены класса которые явно не инициализированы в member initialization list останутся неинициализированными


azesmcar, в чем по твоему принципиальное отличие этих строк, что ты написал такую сильную разницу между ними? Между этими двумя записями нет ровно никакой разницы, исключая то, что в первом случе используется копирующий конструктор. И в первом и во втором случае, все non POD члены будут создан конструктором по умолчанию, а в POD типах будет мусор, если обратного не будет указано в списке инициализации


--------------------
Мой блог
PM MAIL WWW   Вверх
lv151
Дата 19.3.2009, 16:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 916
Регистрация: 11.2.2008

Репутация: нет
Всего: 2



Спасибо.

Был невнимателен. 
Думал что:

Код

MyClass::MyClass()
{
   //тут уже все инициализировано, то что не описано в списке инициализации - инициализируется по умолчанию (если это возможно)
}


: var_(var) - незаметил smile.

Это сообщение отредактировал(а) lv151 - 19.3.2009, 16:33
PM MAIL   Вверх
azesmcar
Дата 19.3.2009, 16:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



vinter, не совсем, 
Код

class MyClass
{
public:
    int a;
};

int main()
{
    MyClass t;
    std::cout << t.a << std::endl;
    MyClass p = MyClass();
    std::cout << p.a << std::endl;
    return 0;
}


результат
Код

2019276528
0


Добавлено через 1 минуту и 47 секунд
если не делать new
Код

MyClass *t = new MyClass(); 


можно так, но MyClass s() компилятор понимает как обявление прототипа функции с возвращаемым типом MyClass.
PM   Вверх
lv151
Дата 19.3.2009, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 916
Регистрация: 11.2.2008

Репутация: нет
Всего: 2



Цитата(azesmcar @  19.3.2009,  16:34 Найти цитируемый пост)
vinter, не совсем, 
Выделить всёкод C++
class MyClass
{
public:
    int a;
};
int main()
{
    MyClass t;
    std::cout << t.a << std::endl;
    MyClass p = MyClass();
    std::cout << p.a << std::endl;
    return 0;
}
    
2019276528
0

 


VC 6.0 
 -858993460
 -858993460

Это сообщение отредактировал(а) lv151 - 19.3.2009, 16:58
PM MAIL   Вверх
vinter
Дата 19.3.2009, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 8
Всего: 56



azesmcar, интересная особенность. Учитывая, что some_class obj; и some_class obj(); эквивалентные записи... 


--------------------
Мой блог
PM MAIL WWW   Вверх
azesmcar
Дата 19.3.2009, 17:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



lv151, VC 6.0 не в счет.

Цитата

azesmcar, интересная особенность. Учитывая, что some_class obj; и some_class obj(); эквивалентные записи...  


это тоже не совсем так, ибо some_class obj(); это обявление прототипа функции с возвращаемым типом some_class не принимающей параметров.
Код

class some_class
{
};

int main()
{
    some_class obj();
    return 0;
}



Цитата

'some_class obj(void)': prototyped function not called (was a variable definition intended?)

PM   Вверх
azesmcar
Дата 19.3.2009, 18:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Добавлю статью из МСДН
http://msdn.microsoft.com/en-us/library/s0wk5dy9.aspx
Код

int main()
{
    // points to unitialized int (value at *pi0 is indeterminate)
    int *pi0 = new int;  

    // pointer to a default initialized int (*pi1 == 0) 
    int *pi1 = new int();

    delete pi0;
    delete pi1;
}


в стандарте пока не нашел, но не думаю что стоит искать
Цитата

 The following sample works in Visual C++ .NET 2003 as specified in the standard: 

не думаю что МСДН врет

Это сообщение отредактировал(а) azesmcar - 19.3.2009, 18:17
PM   Вверх
vinter
Дата 19.3.2009, 18:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 8
Всего: 56



Цитата(azesmcar @  19.3.2009,  19:15 Найти цитируемый пост)
Добавлю статью из МСДНhttp://msdn.microsoft.com/en-us/library/s0wk5dy9.aspx

с этим никто не спорит, если у встроенных типов добавить скобки при определении, тогда она будет проинициализирована 0. У класса нет разницы, есть скобки или нет. Дефолтовый конструктор вызовется в любом случае.НО при этом он не должен обнулять внутренние pod члены. Возможно это фича студии, что при таком выражении оно обнуляет. Я бы не стал на это полагаться.

Добавлено через 1 минуту и 9 секунд
Цитата

 i0 value indeterminate

оттуда же кстати


--------------------
Мой блог
PM MAIL WWW   Вверх
azesmcar
Дата 19.3.2009, 18:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Цитата

НО при этом он не должен обнулять внутренние pod члены. Возможно это фича студии, что при таком выражении оно обнуляет. Я бы не стал на это полагаться.


Я бы тоже не стал, потому что нет никакой гарантии что тот кто будет использовать ваш класс - проинициализирует его со скобками. Но если мне не изменяет память Саттер говорил, что класс проинициализированный со скобками, инициализирует также все внутренние pod члены.

Добавлено через 2 минуты и 20 секунд
Цитата

Возможно это фича студии


щас GCC проверим

Добавлено через 6 минут и 16 секунд
Цитата

[guest@server guest]$ cat test.cpp
#include <iostream>

class MyClass
{
public:
    int a;
};
int main()
{
    MyClass t;
    std::cout << t.a << std::endl;
    MyClass p = MyClass();
    std::cout << p.a << std::endl;
    return 0;
}

[guest@server guest]$ g++ test.cpp
[guest@server guest]$ ./a.out
1506560
0


Добавлено через 10 минут и 51 секунду
Цитата

i0 value indeterminate


ну ясно, потому что класс создан без скобок. Я попробую найти что Саттер писал по этому поводу.
PM   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1911 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.