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

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

Однако, когда я вызвал конструктора, это не имело никакого эффекта... это взяло меня некоторое время для выяснения - но это ничего не повторно инициализировало!

Я создал функцию точно как конструктор - таким образом, объект будет иметь свою собственную версию. Когда я назвал это, это повторно инициализировало все, как я ожидал.

int main()
{
 Class MyClass()

 int counter = 0;

 while ( counter < 1000 )
 { stuff happens }

 Class(); // This is how I tried to call the constructor initially.
          // After doing some reading here, I tried:
          // Class::Class(); 
          // - but that didn't work either 
 /* Later I used...
 MyClass.function_like_my_constructor; // this worked perfectly
 */
}

... Кто-то мог попытаться объяснить, почему то, что я сделал, было неправильно, или не работало или было глупо или что имеет Вас? Я имею в виду - мысленно, я просто фигурировал - дерьмо, я могу вызвать этого конструктора и повторно инициализировать весь этот материал. Конструкторов (Идеально) ТОЛЬКО вызывают, когда объект создается?

6
задан Azoreo 27 March 2010 в 20:39
поделиться

5 ответов

Ваша строка Class (); действительно вызывает конструктор класса Class , но он вызывает его для создания «временного объекта». Поскольку вы не используете этот временный объект, строка не имеет никакого полезного эффекта.

Временные объекты (обычно) исчезают в конце выражения, в котором они появляются. Они полезны для передачи в качестве параметров функции или инициализации других объектов. Практически никогда не бывает полезно просто создать его в одном утверждении. Язык допускает это как допустимое выражение, просто для большинства классов это не очень важно.

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

Class myObject;
// ... do some stuff to myObject ...

myObject = Class();

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

Другой вариант - просто использовать новый объект для каждой итерации:

int main() {
    int counter = 0;
    while (counter < 1000) {
        Class myObject;
        // stuff happens, each iteration has a brand new object
    }
}

Обратите внимание, что Class MyClass (); не определяет объект типа Class, называемый MyClass , и построить его без параметров. Он объявляет функцию MyClass, которая не принимает параметров и возвращает объект типа Class. Предположительно в вашем реальном коде конструктор имеет один или несколько параметров.

8
ответ дан 8 December 2019 в 17:20
поделиться

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

1
ответ дан 8 December 2019 в 17:20
поделиться

Что происходит при чтении этой строки ...

Class ();

То, что вы действительно вызываете конструктор - для временного объекта, который создается с нуля, а затем немедленно уничтожается, так как вы ничего с ним не делаете. Это очень похоже на приведение к классу, которое создает значение с помощью вызова конструктора, за исключением того, что в этом случае нет значения для преобразования, поэтому используется конструктор по умолчанию.

Возможно, что компилятор затем оптимизирует это временное, поэтому конструктора вообще нет - я не уверен, разрешено это или нет.

Если вы хотите повторно инициализировать элементы, вызов конструктора - не способ сделать это.Переместите весь код инициализации в другой метод и вызовите его из своего конструктора, а вместо этого, когда вы захотите выполнить повторную инициализацию.

5
ответ дан 8 December 2019 в 17:20
поделиться

Вы стали жертвой распространенного неправильного прочтения C ++. Новый c ++ 0x проясняет ситуацию.

Проблема в том, что синтаксис конструкций выглядит как вызов функции.

void foo( int i ) { }
class Foo { };

Foo(10); // construct a temporary object of type foo
foo(10); // call function foo
Foo{10}; // construct a temporary object of type foo in c++0x syntax

Я думаю, что синтаксис C ++ 0x более понятен.

С этим синтаксисом вы можете делать все, что хотите. Но будьте осторожны, он очень продвинутый, и вам не следует этого делать.

MyClass.~Class(); // destruct MyClass
new( &MyClass ) Class;
0
ответ дан 8 December 2019 в 17:20
поделиться

При таких требованиях я обычно пишу clear() (public) метод. Я вызываю его из конструктора, деструктора. Пользовательский код может вызвать его, когда захочет.

class Foo
{
  public:

    Foo() { clear(); }

    ~Foo() { clear(); }

    void clear(); // (re)initialize the private members

  private:

     // private members
 };

Чтобы ответить на поставленный здесь вопрос, метод clear() может быть вызван всякий раз, когда требуется повторная инициализация класса, как это было сразу после первоначального построения.

0
ответ дан 8 December 2019 в 17:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: