생성자를 호출하여 개체 다시 초기화
생성자를 사용하여 클래스의 객체를 다시 초기화 할 수 있습니까?
일종의. 클래스 A가 주어지면 :
A a;
...
a = A();
마지막 진술은 초기화가 아니라 할당이지만 아마도 원하는 것을 수행 할 것입니다.
말 그대로? 예, 새 배치를 사용하여. 그러나 먼저 이전에 생성 된 객체를 파괴해야합니다.
SomeClass object(1, 2, 3);
...
object.~SomeClass(); // destruct
new(&object) SomeClass(4, 5, 6); // reconstruct
...
// Final destruction will be done implicitly
이것의 가치는 순수한 이론을 넘어서는 것은 아닙니다. 실제로하지 마십시오. 모든 것이 설명 할 수 없을 정도로 추합니다.
매우 나쁜 생각이지만 가능합니다. 그 이유는 기존 객체에서 소멸자를 호출하지 않으면 리소스가 누출되기 때문입니다.
그 중요한 경고와 함께 그것을 고집한다면 새로운 배치를 사용할 수 있습니다.
// Construct the class
CLASS cl(args);
// And reconstruct it...
new (&cl) CLASS(args);
아니요, 생성자는 객체가 처음 생성 될 때만 호출됩니다. 대신 새 메소드를 작성하십시오.
편집하다
나는 일을 위해 애완 동물 랩터를 구하고 싶지 않기 때문에 새로운 배치를 인정하지 않을 것입니다.
짧은 답변:
아니요. 개체의 의도 된 동작의 일부가 여러 번 초기화되는 경우이를 구현하는 가장 좋은 방법은 액세스 가능한 초기화 메서드를 사용하는 것입니다. 클래스 생성자는이 메서드를 단순히 연기 할 수 있습니다.
class C1 {
public:
C1(int p1, int p2) {
Init(p1,p2);
}
void Init(int p1, int p2) { ... }
};
Nitpicker 코너 :
객체가 생성 된 후 C ++에서 생성자를 호출하는 엄청나게 사악한 방법이 있습니까? 거의 확실하게 이것은 결국 C ++입니다. 그러나 그것은 근본적으로 악하고 행동은 거의 확실하게 표준에 의해 정의되지 않으며 피해야합니다.
C ++ 11에서는 다음과 같이 할 수 있습니다.
#include <type_traits>
template <class T, typename... Args>
void Reconstruct(T& x, Args&&... args)
{
static_assert(!std::has_virtual_destructor<T>::value, "Unsafe");
x.~T();
new (&x) T(std::forward<Args>(args)...);
}
이를 통해 Reconstruct
임의의 생성자 매개 변수를 모든 객체에 전달할 수 있습니다 . 이렇게하면 여러 Clear
메서드 를 유지 관리 할 필요가 Clear
없으며 어떤 지점에서 개체가 변경되고 메서드가 더 이상 생성자와 일치하지 않으면 쉽게 눈에 띄지 않게되는 버그를 방지 할 수 있습니다 .
위의 내용은 대부분의 컨텍스트에서 잘 작동하지만 참조가 가상 소멸자가있는 파생 개체 내의 기본에 대한 것이라면 끔찍하게 실패합니다. 이러한 이유로 위의 구현은 가상 소멸자가있는 개체와 함께 사용하는 것을 방지합니다.
예, 새로운 배치를 속이고 사용할 수 있습니다.
참고 : 나는 이것을 조언하지 않습니다.
#include <new>
reInitAnA(A& value)
{
value.~A(); // destroy the old one first.
new (&value) A(); // Call the constructor
// uses placement new to construct the new object
// in the old values location.
}
나는 일반적으로 현대 C ++에서 다음을 작성합니다.
SomeClass a;
...
a = decltype(a)();
It may be not the most effective way, as it effectively constructs another object of the same type of a
and assigns it to a
, but it works in most cases, you don't have to remember the type of a
, and it adapts if the type changes.
May-be not what you have in mind, but since you didn't mention what it is for, I suppose one answer would be that you'd do it by controlling scope and program flow.
For example, you wouldn't write a game like this:
initialize player
code for level 1
...
reinitialize player
code for level 2
...
etc
Instead you'd strive for:
void play_level(level_number, level_data) {
Player player; //gets "re-initialized" at the beginning of each level using constructor
//code for level
}
void game() {
level_number = 1;
while (some_condition) {
play_level(level_number, level_data);
++level_number;
}
}
(Very rough outline to convey the idea, not meant to be remotely compilable.)
Instead of destructing and reinitializing as suggested by some of the answers above, it's better to do an assignment like below. The code below is exception safe.
T& reinitialize(int x, int y)
{
T other(x, y);
Swap(other); // this can't throw.
return *this;
}
While most answers are reinitializing an object in two steps; first, creating an initial object, and second creating another object and swapping it with the first one using placement new
, this answer covers the case that you first create a pointer to an empty object and later allocate and construct it:
class c *c_instance; // Pointer to class c
c_instance = new c(arg1, ..., argn) // Allocate memory & call the proper constructor
// Use the instance e.g. c->data
delete c_instance; // Deallocate memory & call the destructor
참고URL : https://stackoverflow.com/questions/2166099/calling-a-constructor-to-re-initialize-object
'program story' 카테고리의 다른 글
ExpandableListView -UnsupportedOperationException : addView (View, LayoutParams)는 AdapterView에서 지원되지 않습니다. (0) | 2020.12.07 |
---|---|
계속하려면 아무 키나 누르십시오. (0) | 2020.12.07 |
Python에서 소수의 효율적인 무한 생성기를 구현하는 방법은 무엇입니까? (0) | 2020.12.06 |
Node.js : 각… 작동하지 않음 (0) | 2020.12.06 |
Javascript-배열의 각 문자열에 트림 기능 적용 (0) | 2020.12.06 |