LINUX.ORG.RU

а можно ли так?

 


0

4
class object
{
  public:
    object ( );
    virtual void update ();
    void loop ();
};
object::object ()
{

}

void object::update ()
{
  printf ("object\n");
}

void object::loop ()
{
  while ( 1 )
  {
    sleep ( 1 );
    update ();
  }
}
class pro : public object
{ 
  void update ();
};

void pro::update ()
{
  printf ("pro\n" );
}

Можно ли создать pro и чтобы он писал слово «pro»?



Последнее исправление: u0atgKIRznY5 (всего исправлений: 1)

Что значит «можно»? Смотря чего ты хочешь добиться.

DELIRIUM ☆☆☆☆☆
()

Можно, разрешаю.

anonymous
()

Во-первых, нет, нельзя. Внутри конструктора родителя используются реализации виртуальных методов от родителя. Виртуальные методы потомка начнут использоваться лишь когда отработает его конструктор (а он, по понятным причинам, выполняется после конструктора родителя). Это техническое ограничение C++ и его не обойти. Поэтому в конструкторах не рекомендуется вызывать виртуальные методы вообще, если не знаешь, что делаешь.

Во-вторых, бесконечный цикл в конструкторе - дизайн архитектуры так себе. Лучше сделай отдельный метод, который будешь вызывать сразу после создания объекта.

KivApple ★★★★★
()
Последнее исправление: KivApple (всего исправлений: 1)
Ответ на: комментарий от KivApple

А как тогда например в unity делают такое. Там на с#. Создается класс и наследуется от другого класа. Переопределяет метод update, которые выполняется при каждом обновлении экрана, как он может обновляться? Значит он где-то в коде вписан виртуальный метод? Или у них там все переделывается по другому?

u0atgKIRznY5
() автор топика
Ответ на: комментарий от u0atgKIRznY5

Переопределяет метод update, которые выполняется при каждом обновлении экрана, как он может обновляться?

а он (::update()) там из конструктора вызывается?

да и тег тут вроде c++

samson ★★
()
Последнее исправление: samson (всего исправлений: 1)
Ответ на: комментарий от Dudraug

А что там приводить, создаешь сценарий, порождаешь его от какой то там mono, уже не помню, но unity'товский. В котором метод Start и Update, а также другие. Так вот. В Start или Awake заносятся данные, которые нужны для инициализации, а в Update, то, что будет выполнятся при каждом кадре.

u0atgKIRznY5
() автор топика
Ответ на: комментарий от u0atgKIRznY5

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

Dudraug ★★★★★
()
Ответ на: комментарий от Dudraug

Но очевидно, что бесконечные циклы в конструкторе быть не должны.

У них там unity3d закрытый код, может как то и можно посмотреть, но я незнаю как. Бывало как-то код какой то показывался из какого-то файла, но вряд ли тот который нужен. А что код. Код класса не увидеть, но переопределить функции update можно. Может весь код из update куда нибудь копируется, ну в другую функцию, в которой обновление происходит, а update такая же, как слоты и сигналы в qt, которые потом переводятся в нормальный код, потому что слотов и сигналов в c++ нет.

u0atgKIRznY5
() автор топика
Ответ на: комментарий от u0atgKIRznY5

У них там unity3d закрытый код, может как то и можно посмотреть, но я незнаю как.

Тогда с чего тебе пришла вообще мысль делать беск цикл в конструкторе?

Код класса не увидеть, но переопределить функции update можно.

Так дальнешее использование класса с переопределенными методами например. Ты понимаешь, что произойдет при создание твоего объекта? (с беск циклом в конструкторе)

Dudraug ★★★★★
()
Ответ на: комментарий от u0atgKIRznY5

открою тебе секрет полишенеля, сигналы и слоты в с и с++ называются callback функциями, а так же можно реализовать с помощью boost.signals2

Silerus ★★★★
()
Ответ на: комментарий от Dudraug

причину я могу назвать, он, как обычно поверхностно посмотрел примеры и пошел воять, это не первый его опыт, а как запутался, побежал сюда - не барское дело, книжки читать. На счет шарпа там дела обстоят так: При создании объекта в C#, важно понимать, в каком порядке инициализируются поля и конструкторы объекта:

Статические поля производного класса Статический конструктор производного класса Поля экземпляра производного класса Статические поля базового класса Статический конструктор базового класса Поля экземпляра базового класса Конструктор экземпляра базового класса Конструктор экземпляра производного класса

Silerus ★★★★
()

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


App app;
app.init();
while(app.run())
{
    app.update();
    app.render();
}
app.release();

мы свои «мега движки» по такому принципу делали

jo_b1ack ★★★★★
()
Последнее исправление: jo_b1ack (всего исправлений: 2)
Ответ на: комментарий от u0atgKIRznY5

Пичем тут unity и C#. Вы вопрос по плюсам задаете.

Кстати, черным по белому написано же:

https://it.wikireading.ru/28384
Если вы – программист на Java или C#, то обратите на это правило особое внимание, потому что это в этом отношении C++ ведет себя иначе.

Сам себе ответь на вопрос: как вызвать метод еще не сконструированного объекта (точнее, как ему будет передан указатель на экземпляр еще не сконструированного объекта)? При создании объекта производного класса вызывается его конструктор, который сначала вызывает конструктор базового класса, а в нем вызывается виртуальный метод. А вы там еще и зациклить хотите.

Скомпилируй/запусти следующий пример. Посмотри порядок вызова конструкторов/методов и сразу все станет ясно:

// g++ vcallFromConsrAndVDestr.cpp && ./a.out

#include <iostream>

using namespace std;

struct Base {
  Base() {
    cout << "Base::Base()" << endl
	 << "virtual call from constructor... " ;
    vcall();
    
    // while (true) ;  // !!!
  }
  
  // virtual void vcall() = 0;   // compile time warning: pure virtual ‘virtual void Base::vcall()’ called from constructor
                                 // ld error: undefined reference to `Base::vcall()'
  
  virtual void vcall() { cout << "Base::vcall()" << endl; }

  // virtual  // not virtual!!!
  ~Base() { cout << "Base:~Base()" << endl;}  
};

struct Deliv : public Base {
  Deliv() { cout << "Deliv::Deliv()" << endl; }
  
  virtual void vcall() override { cout << "Deliv::vcall()" << endl;  }
  
  ~Deliv() { cout << "Deliv::~Deliv()" << endl; }
};

int main() {
  cout << "------ 7. Declare destructors virtual in polymorphic base classes: " << endl;
  Base* b = new Deliv();
  delete b;

  cout << "------ 9. Never Call Virtual Functions during Construction or Destruction: " << endl;
  Deliv d;

  return 0;
}

В общем, все уже объяснили ранее.

ps: А еще лучше потратить время на чтение Effective C++ Скотта Майерса - это классика, вместо того, что бы задавать такие вопросы на форуме. И вопросы сразу отпадут и время с толком будет потрачено...

pps: не силен ни в unity ни в C#, но что-то подсказывает, что там этот update() не из конструктора вызывается (а из какого-либо init(), run() и т.д.).

samson ★★
()

По вашему коду:

object::object ()
{
  while ( 1 )  // конструктор не завершится,
               // значит и не завершится (даже не начнет выполняться) конструктор производного класса,
               // значит объект производного класса сконструирован не будет!!!
  {
    sleep ( 1 );
    update ();  // как на этом этапе вызвать pro::update(),
                // если экземпляр pro еще не существует???
  }
}

samson ★★
()
Последнее исправление: samson (всего исправлений: 1)
Ответ на: комментарий от u0atgKIRznY5

спасибо что оповестил, продолжай в том же духе

Silerus ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.