문제

C ++에서 변수를 인스턴스화하지 않고 선언 할 수 있습니까? 나는 다음과 같은 일을하고 싶다 :

Animal a;
if( happyDay() ) 
    a( "puppies" ); //constructor call
else
    a( "toads" );

기본적으로, 나는 단지 조건부 외부를 선언하여 올바른 범위를 얻고 싶습니다.

포인터를 사용하고 할당하지 않고이 작업을 수행 할 수있는 방법이 있습니까? a 힙에? 참조로 영리한 것이 있습니까?

도움이 되었습니까?

해결책

기본 생성자로 정의 할 때 객체가 구성되므로 C ++에서 직접 할 수 없습니다.

그러나 시작하여 매개 변수화 된 생성자를 실행할 수 있습니다.

Animal a(getAppropriateString());

또는 실제로와 같은 것을 사용할 수 있습니다 ?: operator 올바른 문자열을 결정합니다. (업데이트 : @Greg는 이것에 대한 구문을 주었다. 그 답을 참조하십시오)

다른 팁

생성자를 호출하지 않고는 변수를 선언 할 수 없습니다. 그러나 예에서는 다음을 수행 할 수 있습니다.

Animal a(happyDay() ? "puppies" : "toads");

범위를 벗어나 자마자 참조를 사용할 수 없습니다. 참조는 삭제 될 객체를 가리 킵니다.

실제로 여기에는 두 가지 선택이 있습니다.

1- 포인터와 함께 이동 :

Animal* a;
if( happyDay() ) 
    a = new Animal( "puppies" ); //constructor call
else
    a = new Animal( "toads" );

// ...
delete a;

2- init 메소드를 추가하십시오 Animal:

class Animal 
{
public:
    Animal(){}
    void Init( const std::string& type )
    {
        m_type = type;
    }
private:
    std:string m_type;
};

Animal a;
if( happyDay() ) 
    a.Init( "puppies" );
else
    a.Init( "toads" );

나는 개인적으로 옵션 2와 함께 갈 것입니다.

나는 Greg의 대답을 선호하지만 이것도 할 수 있습니다.

char *AnimalType;
if( happyDay() ) 
    AnimalType = "puppies";
else
    AnimalType = "toads";
Animal a(AnimalType);

조건부 운영자가 금지 된 장소에서 일했기 때문에 이것을 제안합니다. (한숨!) 또한, 이것은 두 가지 대안을 넘어서 매우 쉽게 확장 될 수 있습니다.

쓰레기 수집을 피하려면 스마트 포인터를 사용할 수 있습니다.

auto_ptr<Animal> p_a;
if ( happyDay() )
    p_a.reset(new Animal( "puppies" ) );
else
    p_a.reset(new Animal( "toads" ) );

// do stuff with p_a-> whatever.  When p_a goes out of scope, it's deleted.

여전히 사용하려는 경우. -> 대신 구문은 위의 코드 후에이를 수행 할 수 있습니다.

Animal& a = *p_a;

// do stuff with a. whatever

Greg Hewgill의 답변 외에도 몇 가지 다른 옵션이 있습니다.

코드의 본체를 함수로 들어 올립니다.

void body(Animal & a) {
    ...
}

if( happyDay() ) {
  Animal a("puppies");
  body( a );
} else {
  Animal a("toad");
  body( a );
}

(ab) 배치 사용 New :

struct AnimalDtor {
   void *m_a;
   AnimalDtor(void *a) : m_a(a) {}
   ~AnimalDtor() { static_cast<Animal*>(m_a)->~Animal(); }
};

char animal_buf[sizeof(Animal)]; // still stack allocated

if( happyDay() )
  new (animal_buf) Animal("puppies");
else
  new (animal_buf) Animal("toad");

AnimalDtor dtor(animal_buf); // make sure the dtor still gets called

Animal & a(*static_cast<Animal*>(static_cast<void*>(animal_buf));
... // carry on

가장 좋은 작업은 포인터를 사용하는 것입니다.

Animal a*;
if( happyDay() ) 
    a = new Animal( "puppies" ); //constructor call
else
    a = new Animal( "toads" );

예, 다음을 수행 할 수 있습니다.

Animal a;
if( happyDay() )
    a = Animal( "puppies" );
else
    a = Animal( "toads" );

그것은 생성자를 올바르게 호출합니다.

편집 : 한 가지를 잊어 버렸습니다 ... A를 선언 할 때는 아무것도하지 않는 생성자이든 여전히 값을 초기화하는지 여부에 관계없이 생성자를 여전히 호출해야합니다. 따라서이 메소드는 초기화시 하나와 IF 문 안에있는 두 개의 객체를 만듭니다.

더 나은 방법은 클래스의 init () 함수를 작성하는 것입니다.

Animal a;
if( happyDay() )
    a.init( "puppies" );
else
    a.init( "toads" );

이 방법은 더 효율적입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top