나를 놀라게 한 코드를 발견했습니다. 는 본질적으로는이 패턴 다음 :이 코드는 년 동안 코드베이스되었습니다C++ 배치를 사용하여 객체를 두 번 생성 중입니다. 새 정의되지 않은 동작입니까?
class Foo
{
public:
//default constructor
Foo(): x(0), ptr(nullptr)
{
//do nothing
}
//more interesting constructor
Foo(FooInitialiser& init): x(0), ptr(nullptr)
{
x = init.getX();
ptr = new int;
}
~Foo()
{
delete ptr;
}
private:
int x;
int* ptr;
};
void someFunction(FooInitialiser initialiser)
{
int numFoos = MAGIC_NUMBER;
Foo* fooArray = new Foo[numFoos]; //allocate an array of default constructed Foo's
for(int i = 0; i < numFoos; ++i)
{
new(fooArray+ i) Foo(initialiser); //use placement new to initialise
}
//... do stuff
delete[] fooArray;
}
를하고 문제가 발생하지 않았다 보인다. 누군가가 기본 생성자를 변경하여 두 번째 구성을 기대하지 않도록 할당 할 수 있으므로 분명히 나쁜 생각입니다. 두 번째 생성자를 동등한 초기화 메소드로 바꾸는 것만으로도 합리적인 것처럼 보일 것입니다. 예.
void Foo::initialise(FooInitialiser& init)
{
x = init.getX();
ptr = new int;
}
여전히 리소스 유출 가능성이 있지만 적어도 방어적인 프로그래머는 정상적인 방법으로 사전 할당을 확인한다고 생각할 수 있습니다.
내 질문은 :
는 표준 또는 단순히 나쁜 생각에 의해 금지 /이 실제로 정의되지 않은 동작처럼 두 번 구성되어 있습니까? 정의되지 않은 동작을 사용하면 견적을 작성하거나 표준을 볼 수있는 적절한 곳으로 안내 할 수 있습니까?
이 코드에서 valgrind를 사용해 보셨습니까? – zoska
내가 보는 주된 문제점은'Foo'가 3 가지 규칙을 따르지 않는다는 것입니다. 기본 복사와 복사 할당 연산자는'Foo :: ptr'로 올바른 일을하지 않을 것입니다. – cdhowie
@cdhowie 어쩌면 우리는 다른 사람들의 코드에 대해 최악의 상황을 가정해서는 안됩니다. OP는 단순히 질문을 할 필요가없는 코드를 잘라낸 것 같습니다. – anatolyg