Я хотел выполнить 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
*/
}
... Кто-то мог попытаться объяснить, почему то, что я сделал, было неправильно, или не работало или было глупо или что имеет Вас? Я имею в виду - мысленно, я просто фигурировал - дерьмо, я могу вызвать этого конструктора и повторно инициализировать весь этот материал. Конструкторов (Идеально) ТОЛЬКО вызывают, когда объект создается?
Ваша строка 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. Предположительно в вашем реальном коде конструктор имеет один или несколько параметров.
Да, это нетипичное использование. Создайте функцию, которая сбрасывает ваши переменные, и вызывайте метод всякий раз, когда вам это нужно.
Что происходит при чтении этой строки ...
Class ();
То, что вы действительно вызываете конструктор - для временного объекта, который создается с нуля, а затем немедленно уничтожается, так как вы ничего с ним не делаете. Это очень похоже на приведение к классу, которое создает значение с помощью вызова конструктора, за исключением того, что в этом случае нет значения для преобразования, поэтому используется конструктор по умолчанию.
Возможно, что компилятор затем оптимизирует это временное, поэтому конструктора вообще нет - я не уверен, разрешено это или нет.
Если вы хотите повторно инициализировать элементы, вызов конструктора - не способ сделать это.Переместите весь код инициализации в другой метод и вызовите его из своего конструктора, а вместо этого, когда вы захотите выполнить повторную инициализацию.
Вы стали жертвой распространенного неправильного прочтения 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;
При таких требованиях я обычно пишу clear()
(public) метод. Я вызываю его из конструктора, деструктора. Пользовательский код может вызвать его, когда захочет.
class Foo
{
public:
Foo() { clear(); }
~Foo() { clear(); }
void clear(); // (re)initialize the private members
private:
// private members
};
Чтобы ответить на поставленный здесь вопрос, метод clear()
может быть вызван всякий раз, когда требуется повторная инициализация класса, как это было сразу после первоначального построения.