Мелкий copy: Копирует членские значения с одного объекта в другого.
Глубокий Copy: Копирует членские значения с одного объекта в другого.
Любые объекты указателя дублированы и Глубоко Скопированы.
Пример:
class String
{
int size;
char* data;
};
String s1("Ace"); // s1.size = 3 s1.data=0x0000F000
String s2 = shallowCopy(s1);
// s2.size =3 s2.data = 0X0000F000
String s3 = deepCopy(s1);
// s3.size =3 s3.data = 0x0000F00F
// (With Ace copied to this location.)
Макросы препроцессора - это просто шаблоны подстановки, применяемые к вашему коду. Их можно использовать практически в любом месте вашего кода, потому что они заменяются их расширениями перед началом любой компиляции.
Встроенные функции - это фактические функции, тело которых напрямую вводится в их место вызова. Их можно использовать только там, где уместен вызов функции.
Теперь, что касается использования макросов и встроенных функций в функционально-подобном контексте, имейте в виду, что:
inline functions are similar to macros (because the function code is expanded at the point of the call at compile time), inline functions are parsed by the compiler, whereas macros are expanded by the preprocessor. As a result, there are several important differences:
In some cases, expressions passed as arguments to macros can be evaluated more than once. http://msdn.microsoft.com/en-us/library/bf6bf4cf.aspx
macros are expanded at pre-compile time, you cannot use them for debugging, but you can use inline functions.
-- good article: http://www.codeguru.com/forum/showpost.php?p=1093923&postcount=1
;
С точки зрения кодирования встроенная функция похожа на функцию. Таким образом, различия между встроенной функцией и макросом такие же, как и различия между функцией и макросом.
С точки зрения компиляции встроенная функция похожа на макрос. Он вводится непосредственно в код, а не вызывается.
В общем, вы должны рассматривать встроенные функции как обычные функции с добавлением некоторой незначительной оптимизации. И, как и большинство оптимизаций, компилятор должен решить, действительно ли он заботится применить это. Часто компилятор с радостью игнорирует любые попытки программиста встроить функцию по разным причинам.
В GCC (я не уверен в других) объявление функции встроенной - это просто подсказка для компилятора. В конце концов, компилятор должен решить, будет ли он включать тело функции при каждом ее вызове.
Разница между встроенными функциями и макросами препроцессора относительно велика. Макросы препроцессора - это просто замена текста в конце концов. Вы отказываетесь от многих возможностей компилятора выполнять проверку проверки типов аргументов и возвращаемого типа. Оценка аргументов сильно отличается (если выражения, которые вы передаете в функции, имеют побочные эффекты, вам будет очень интересно провести время за отладкой). Существуют тонкие различия в том, где можно использовать функции и макросы. Например, если бы у меня было:
#define MACRO_FUNC(X) ...
Где MACRO_FUNC, очевидно, определяет тело функции. Следует проявлять особую осторожность, чтобы она работала правильно во всех случаях, когда функция может быть использована, например, плохо написанный MACRO_FUNC вызовет ошибку в
if(MACRO_FUNC(y)) {
...body
}
. Обычная функция может быть использована без проблем.
Встроенная функция будет поддерживать семантику значения, тогда как макрос препроцессора просто копирует синтаксис. Вы можете получить очень тонкие ошибки с макросом препроцессора, если вы используете аргумент несколько раз - например, если аргумент содержит мутацию типа «i ++», выполнение этого дважды является большим сюрпризом. У встроенной функции этой проблемы не будет.
Встроенная функция синтаксически ведет себя так же, как обычная функция, обеспечивая безопасность типов и область для локальных переменных функции и доступ к члены класса, если это метод. Также при вызове встроенных методов вы должны придерживаться частных / защищенных ограничений.
Макросы игнорируют пространства имен. И это делает их злыми.
Чтобы добавить еще одно отличие к уже приведенным: вы не можете пройти через #define
в отладчике, но вы можете пройти через встроенную функцию.
Ключевым отличием является проверка типов. Компилятор проверит, имеет ли то, что вы передаете в качестве входных значений, типы, которые могут быть переданы в функцию. Это не относится к макросам препроцессора - они раскрываются перед любой проверкой типов, и это может вызвать серьезные и трудные для обнаружения ошибки.
Здесь описаны несколько других менее очевидных моментов.
Во-первых, макросы препроцессора просто копируют и вставляют в код перед компиляцией. Таким образом, нет проверки типа , и могут появиться некоторые побочные эффекты
Например, если вы хотите сравнить 2 значения:
#define max(a,b) ((a<b)?b:a)
Побочные эффекты появляются, если вы используете max (a ++, b ++)
например ( a
или b
будут увеличены вдвое).
Вместо этого используйте (например)
inline int max( int a, int b) { return ((a<b)?b:a); }