Объявление объекта прежде, чем инициализировать его в C++

Другой вариант использования dplyr - использовать оператор case_when следующим образом:

df$Num_grade <- NA
df <- mutate(df, Num_grade = case_when(
   grades == 'A' ~ 13,
   grades == 'A-' ~ 12,
   grades == 'B+' ~ 11,
   .
   .
   .
   grades == 'F-' ~ 1
))

, который работает во многом как несколько операторов ifelse, но, на мой взгляд, легче понять

45
задан asheeshr 13 March 2013 в 00:48
поделиться

7 ответов

Вы не можете сделать это напрямую в C ++, поскольку объект создается, когда вы определяете его с помощью конструктора по умолчанию.

Однако вы можете запустить параметризованный конструктор для начала:

Animal a(getAppropriateString());

Или вы можете использовать что-то вроде оператора ?: для определения правильной строки. (Обновление: @Greg дал синтаксис для этого. См. Ответ)

33
ответ дан 7 November 2019 в 14:47
поделиться

Вы не можете объявить переменную без вызова конструктора. Однако в вашем примере вы можете сделать следующее:

Animal a(happyDay() ? "puppies" : "toads");
41
ответ дан 7 November 2019 в 14:47
поделиться

Вы не можете использовать ссылки здесь, поскольку, как только вы выйдете из области видимости, ссылка будет указывать на объект, который будет удален.

Действительно, у вас есть здесь есть два варианта:

1- Идти с указателями:

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

// ...
delete a;

2- Добавить метод Init к Животное :

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.

22
ответ дан 7 November 2019 в 14:47
поделиться

Я предпочитаю ответ Грега, но вы также можете сделать это:

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

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

16
ответ дан 7 November 2019 в 14:47
поделиться

Если вы хотите избежать сбора мусора - вы можете использовать умный указатель.

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
7
ответ дан 7 November 2019 в 14:47
поделиться

В дополнение к ответу Грега Хьюгилла есть еще несколько вариантов:

Поднять основную часть кода в функцию:

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
6
ответ дан 7 November 2019 в 14:47
поделиться

Да, вы можете сделать следующее:

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" );

Этот способ был бы более эффективным.

-4
ответ дан 7 November 2019 в 14:47
поделиться
Другие вопросы по тегам:

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