В Java все переменные, которые вы объявляете, на самом деле являются «ссылками» на объекты (или примитивы), а не самими объектами.
При попытке выполнить один метод объекта , ссылка просит живой объект выполнить этот метод. Но если ссылка ссылается на NULL (ничего, нуль, void, nada), то нет способа, которым метод будет выполнен. Тогда runtime сообщит вам об этом, выбросив исключение NullPointerException.
Ваша ссылка «указывает» на нуль, таким образом, «Null -> Pointer».
Объект живет в памяти виртуальной машины пространство и единственный способ доступа к нему - использовать ссылки this
. Возьмем этот пример:
public class Some {
private int id;
public int getId(){
return this.id;
}
public setId( int newId ) {
this.id = newId;
}
}
И в другом месте вашего кода:
Some reference = new Some(); // Point to a new object of type Some()
Some otherReference = null; // Initiallly this points to NULL
reference.setId( 1 ); // Execute setId method, now private var id is 1
System.out.println( reference.getId() ); // Prints 1 to the console
otherReference = reference // Now they both point to the only object.
reference = null; // "reference" now point to null.
// But "otherReference" still point to the "real" object so this print 1 too...
System.out.println( otherReference.getId() );
// Guess what will happen
System.out.println( reference.getId() ); // :S Throws NullPointerException because "reference" is pointing to NULL remember...
Это важно знать - когда больше нет ссылок на объект (в пример выше, когда reference
и otherReference
оба указывают на null), тогда объект «недоступен». Мы не можем работать с ним, поэтому этот объект готов к сбору мусора, и в какой-то момент VM освободит память, используемую этим объектом, и выделит другую.
Да, но только начиная с VC ++ 2005. Синтаксис для Вашего примера был бы:
#define DBGPRINT(fmt, ...) printf(fmt, __VA_ARGS__)
А полная ссылка здесь .
Да, можно сделать это в C++ Visual Studio в версиях 2005 и вне (не уверенный в VS 2003). Смотрите на VA_ARGS. Можно в основном сделать что-то вроде этого:
#define DBGPRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
и аргументы переменной к макросу будет передан функции, обеспеченной как '...' args, где Вы можете тогда нас va_args для парсинга их.
может быть странное поведение с VA_ARGS и использование макросов. Поскольку VA_ARGS является переменным, который означает, что может быть 0 аргументов. Это могло бы оставить Вас с запаздывающими запятыми, где Вы не предназначали.
Если Вы не хотите использовать нестандартные расширения, необходимо обеспечить дополнительные скобки:
#define DBGPRINT(args) printf(args);
DBGPRINT(("%s\n", "Hello World"));
Что Вы ищете, названы [variadic макросами] ( http://msdn.microsoft.com/en-us/library/ms177415 (По сравнению с 80) .aspx) .
Сводка ссылки: да, от VC ++ 2005 на.
Если Вам на самом деле не нужна ни одна из функций макросов (__FILE__
, __LINE__
, вставка маркера, и т.д.) можно хотеть рассмотреть запись функции variadic использования stdargs.h
. Вместо того, чтобы звонить printf()
, функция variadic может звонить vprintf()
для проведения списков аргумента переменной.
Следующее должно работать. (См. ссылку на макросы Variadic )
(Пример ниже показывает фиксированные и аргументы переменной.)
# define DBGPRINTF(fmt,...) \
do { \
printf(fmt, __VA_ARGS__); \
} while(0)
Почти. Это более ужасно, чем это, хотя (и Вы, вероятно, не хотите запаздывающую точку с запятой в самом макросе:
#define DBGPRINT(DBGPRINT_ARGS) printf DBGPRINT_ARGS // note: do not use '(' & ')'
Для использования его:
DBGPRINT(("%s\n", "Hello World"));
(пропускал пару parens).
Не уверенный, почему все отрицательные стороны, исходный вопрос не указывал, версия VC ++, и variadic макросы не поддерживается всеми компиляторами.