C++ Переопределение... перезапись?
Я знаю, что такое переопределение в C++. Но есть ли перезапись? Если так, что это значит?
Благодарю.
6 ответов
В терминологии C++ у вас есть переопределение (относящееся к виртуальным методам в иерархии классов) и перегрузка (относящиеся к функции, имеющей одно и то же имя, но принимающей разные параметры). У вас также есть скрытие имен (через явное объявление того же имени во вложенной декларативной области или области).
Стандарт C++ не использует термин "перезапись", кроме как в его канонической английской форме (то есть, чтобы заменить одно значение новым значением, как в присваивании x = 10
который перезаписывает предыдущее значение x
).
Вы можете перезаписать переменные, например, int a = 0; a = 42;
и файлы (откройте существующий файл для записи - если у вас есть разрешение, он перезапишет существующее содержимое файла), если вы это имеете в виду. Это имеет мало общего с переопределением. Вы возможно думали о перегрузке?
Обычное различие, с которым я знаком, состоит в перегрузке и перегрузке. Виртуальные функции переопределяются. Функции перегружаются, когда есть версия с тем же именем, но с другой подписью (это существует во многих языках). В C++ вы также можете перегружать операторы.
AFAIK, перезапись является несвязанной концепцией (перезапись переменной, файла, буфера и т. Д.) И не является специфичной для C++ или даже для языков ООП.
Переопределение - это "нормальная вещь" в ООП: производный класс предоставляет другую (то есть более специализированную) реализацию для чего-то, переопределяя базовый класс, например apple::foo()
Переопределение fruit::foo()
если яблоко является классом, полученным из фруктов. (не путать с перегрузкой, используя разные сигнатуры параметров, что приводит к совершенно разным функциям).
Перезаписать я знаю как полностью заменить на другое-определение. Не на определенном уровне, но в целом для остальной части программы. Иногда используется javascript, если у большого фреймворка есть какие-то особые проблемы, и вы не хотите разбивать большой файл на части:
<script type="text/javascript"
src="some super big framework, often in one big file">
<script type="text/javascript">
Ext.ux.window.createWin = function() {
// completely OVERWRITE the implementation
(often to 'hotfix' a particular bug)
}
</script>
Однако: я не знаю ничего подобного в C++, так как одновременное переопределение функции всегда приводило бы к ошибкам уже во время компиляции. В лучшем случае я могу отображать указатели на функции изгиба или (пере) определять перехватчики обратного вызова.
Переопределение функций C++. Если производный класс определяет ту же функцию, которая определена в его базовом классе, в C++ это называется переопределением функции. Он используется для достижения полиморфизма во время выполнения. Это позволяет вам предоставить конкретную реализацию функции, которая уже предоставлена его базовым классом.
Переопределение означает создание метода с ключевым словом virtual в базовом классе, а базовый класс позволяет дочерним классам создавать для себя тело того же метода.
Перезапись означает переопределение без виртуального ключевого слова.
Перегрузка означает создание нескольких методов с разными входными параметрами с одним именем.
ОБРАЗЦЫ:
#include <stdio.h>
#include <stdlib.h>
class par_overwrite
{public: par_overwrite() {}; ~par_overwrite() {};
int at() { return 1; };
};
class chld_overwrite :public par_overwrite
{public: chld_overwrite() {}; ~chld_overwrite() {};
int at() { return 2; }//overwrite
};
void main_overwrite()
{
par_overwrite pt;
int ptat = pt.at();
chld_overwrite ct;
int ctat = ct.at();
printf("ptat:%d,ctat:%d\n",ptat, ctat); //output : ptat:1,ctat:2
}
class par_override
{public: par_override() {}; ~par_override() {};
virtual int ad() { return 3; };
};
class chld_override :public par_override
{public: chld_override() {}; ~chld_override() {};
int ad() { return 4; }//override
};
void main_override()
{
par_override pd;
int pdad = pd.ad();
chld_override cd;
int cdad = cd.ad();
printf("pdad:%d,cdad:%d\n", pdad, cdad); //output : pdad:3,cdad:4
}
class par_override_pure
{public: par_override_pure() {}; ~par_override_pure() {};
virtual int adp()=0;//Pure Virtual Function
};
class chld_override_pure :public par_override_pure
{public: chld_override_pure() {}; ~chld_override_pure() {};
int adp() { return 5; }//override from Pure Virtual Function
};
void main_override_pure()
{
//par_override_pure pdp;//error : Can not create object from abstract class that have (Pure Virtual Function)
//int pdpad = pdp.ad();//error
chld_override_pure cdp;
int cdpadp = cdp.adp();
printf("cdpadp:%d\n", cdpadp); //output : cdpadp:5
}
class overload
{public: overload() {}; ~overload() {};
void method_overload(int prm1) { printf("ol1\t"); }
void method_overload(int prm1, int prm2) { printf("ol2\t"); }
void method_overload(int prm1, int prm2, int prm3) { printf("ol3\t"); }
void method_overload(double prm1) { printf("ol4\t"); }
void method_overload(double prm1, double prm2) { printf("ol5\t"); }
void method_overload(double prm1, double prm2, double prm3) { printf("ol6\t"); }
};
void main_overload()
{
overload ol;
ol.method_overload(1);
ol.method_overload(1, 1);
ol.method_overload(1, 1, 1);
ol.method_overload(0.1);
ol.method_overload(0.1, 0.1);
ol.method_overload(0.1, 0.1, 0.1); // output : ol1 ol2 ol3 ol4 ol5 ol6
}
int main()
{ main_overwrite();
main_override();
main_override_pure();
main_overload();
getchar();
return 0;
}
/* output:
ptat:1,ctat:2
pdad:3,cdad:4
cdpadp:5
ol1 ol2 ol3 ol4 ol5 ol6
*/