2010-04-06 3 views
3

Как инициализировать по умолчанию локальную переменную примитивного типа в C++? Например, если у ЬурейеЕ:Как по умолчанию инициализировать локальные переменные встроенных типов в C++?

typedef unsigned char boolean;//that's Microsoft RPC runtime typedef 

Я хотел бы изменить следующую строку:

boolean variable = 0; //initialize to some value to ensure reproduceable behavior 
retrieveValue(&variable); // do actual job 

в то, что будет по умолчанию автоматически инициализировать переменную - не нужно назначить определенное значение для него, но вместо этого мне нужно только, чтобы это было intialized к тому же значению каждый раз, когда программа работает - тот же материал, как со списком конструктор инициализатора, где я могу иметь:

struct Struct { 
    int Value; 
    Struct() : Value() {} 
}; 

, а Struct::Value будет инициализирован по умолчанию для одного и того же значения каждый раз, когда экземпляр cinstructed, но я никогда не записываю фактическое значение в коде.

Как я могу получить то же поведение для локальных переменных?

+0

Что вы пытаетесь достичь? Может ли помочь Mabe боксирование примитивной переменной в объекте? – clyfe

+0

@clyfe: Я не хочу иметь фактическое значение в моем коде, так как это не имеет значения. – sharptooth

+0

Я не уверен, что именно вы хотите. Вы хотите автоматически использовать 'T obj;' default-initialize 'obj' даже для встроенных модулей? Это невозможно. Или вам просто нужен способ по умолчанию инициализировать 'obj' независимо от того, какой тип он имеет? Затем, как уже говорят некоторые ответы, 'T obj = T();' это путь. – sbi

ответ

5

Вы можете эмулировать что поведение следующим образом:

boolean x = boolean(); 

или, более общее,

T x = T(); 

Это будет по умолчанию инициализировать x, если такая инициализация по умолчанию существует. Однако просто писать T x никогда не будет делать трюк для локальных переменных, независимо от того, что вы делаете.

Вы также можете использовать размещение нового для вызова «конструктора», даже для POD:

T x; 
new (&x) T(); 

Обратите внимание, что этот код вызывает неопределенное поведение для неконтактного типа POD (в частности, для типов, которые имеют непустой тривиальный деструктор). Для того, чтобы сделать этот код работать с определенными пользователем типами, сначала нужно вызвать деструктор объекта:

T x; 
x.~T(); 
new (&x) T(); 

Этот синтаксис может также использоваться для стручков (гарантируемых §§5.2.4/12.4.15) поэтому вышеуказанный код можно использовать без разбора для любого типа.

+0

Я полагаю, что для UDT последнее вызывает UB, поскольку ctor не вызывается в необработанной памяти, а на уже построенном объекте. – sbi

+0

@sbi: true: для UDT последний * должен * сначала вызвать деструктор. Я говорил только о POD, но я уточню это, чтобы предотвратить недоразумения. –

+0

'x. ~ T();' действительно работает в шаблоне, где 'T' является' int'. Тем не менее, запись того же буквально ('x ~ int();') терпит неудачу как с VC9, так и с Комо. – sbi

4
int var = int(); 
    string str = string(); 
    ... 

... или любой другой тип, который вы хотите.

+0

Фактически это не отличается от ввода int var = 0; строка str; –

+0

... и это больше печатает и менее читаемо. –

+3

@kotlinski: есть но * сменный *. Он работает с любым типом имени без необходимости изменения литерала. Конечно, для такого кода, как указано выше, это мало смысла. Однако это имеет смысл при использовании в сочетании с шаблонами. –

0

Обертка в struct (Boolean), как в вашем примере, и доступ через открытый элемент (Boolean :: value). Это может быть не самое изящное решение (немного крутое для небольшой выгоды), но оно похоже на то, что вы уже показали.

1

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

#include <cassert> 

template <class T> 
class Type 
{ 
    T t; 
public: 
    Type(const T& t = T()): t(t) {} 
    operator T&() { return t; } 
    operator const T&() const { return t; } 
}; 

int main() 
{ 
    Type<unsigned char> some_value; 
    assert(some_value == '\0'); 
} 

Это должно быть довольно хорошо использовать для операторов преобразования.

0

Если я понимаю исходный вопрос, плакат говорит, что хочет, чтобы переменные данного типа всегда имели одинаковое начальное значение, но ему все равно, что это за значение, потому что он никогда не будет смотреть на него. Я прав?

Если да, то мой вопрос для плаката таков: если вы не инициализировали переменные, у них были бы случайные начальные значения ... но вы сказали, что никогда не смотрите на начальные значения - так почему это имеет значение, re random?

Я думаю, что ключевым вопросом является то, что вы пытаетесь достичь здесь?

+0

Неинициализированные переменные могут вводить невоспроизводимое поведение. Одна и та же переменная может иметь разные значения для разных программ. Этого я не хочу. – sharptooth

+0

@joefis: Если вы хотите попросить разъяснения по вопросу использовать комментарии, а не ответы. –

+0

> Одна и та же переменная может иметь разные значения > в разных программах. OK, но это относится только к тому, что вы получаете доступ к значениям неинициализированных переменных, которые являются ошибкой ... – eemz

Смежные вопросы