При программировании классов функции, описываемые для класса, можно описывать непосредственно внутри класса или выносить за пределы класса, оставляя внутри класса только прототипы. Когда функции получаются большими, т. е. содержат много текстового кода, и функций в классе собрано немало, сильно страдает читаемость кода. Чтобы видеть скелет класса, т. е. понимать саму идею класса: ради чего он существует, что можно делать порождаемым от него объектом и т. д. — очень удобно выносить функции, принадлежащие классу, за класс.
Чтобы вынести функции класса за пределы класса, нужно использовать операцию разрешения контекса, в народе — двойное двоеточие: ::.
Для выноса функций из класса, но оставления принадлежности функций к классу, внутри класса оставляются прототипы выносимых за пределы класса функций, а вне класса функциям уточняют принадлежность объекта к классу с помощью операции разрешения контекста.
Чтобы понять отмеченное, нужно посмотреть код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//Листинг #1 Вынесение функций класса за пределы класса Borland C++3.1
#include <conio.h>
#include <iostream.h>
classMyClass
{
inta;//Переменная а доступна только внутри класса MyClass
public:
MyClass();//Прототип конструктора
voidshow_a();//Прототип функции show_a()
}obj1;//obj1 - Переменная типа MyClass. Здесь описание класса закончено, обязательны точка с запятой
//Для описания методов вне класса используют операцию разрешения контекста
MyClass::MyClass()//Класс::Конструктор Конструктор не возвращает никаких значений
{
cout<<"Wwedi a: ";//В конструкторе выполняется ввод значения в а с клавиатуры
cin>>a;
}
voidMyClass::show_a()//С помощью двойного двоеточия уточняем принадлежность функции show_a к классу MyClass
{
cout<<a<<endl;//Функция выводит на экран значение a из класса MyClass
}
//Описание методов вне класса закончено
//++++++++++++++++++++++++++++++++++++++++++
intmain()
{
clrscr();//Очистка экрана для очистки при первом запуске
obj1.show_a();//Показали а
cin.get();//Ожидание нажатия Enter
clrscr();//Чистим экран
}
Общий вид представления функции остаётся таким же, как если бы функция была обычной, за исключением того, что к названию функцию дописывается уточняющее принадлежность к классу обозначение.
C++
1
voidMyClass::show_a()//Уточнённое название функции
Операция разрешения контекста идентифицирует класс, к которому метод относится. Говорят, что идентификатор show_a() имеет область видимости класса.
Название функции с применением к ней уточняющего класс двойного двоеточия называется уточнённым именем функции.
Если функции класса не выносить за пределы класса, то тогда использовать уточнение имени необязательно.
Между функциями, описанными в классе, и функциями, вынесенными за класс, имеются различия. Совсем новичку трудно объяснить их очень просто, поэтому если вы пока ещё не продвинутые новички, то просто знайте, что различия есть. Особенно резко они проявляются при написании многофайлофых проектов. Если вы продвинутый новичок, то можете почитать, что это за различия такие, они описываются ниже.
Функции, определённые внутри класса, всегда inline, поэтому им не обязательно явно прописывать inline. Для выносимых за пределы класса функций в случае необходимости inline писать обязательно:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//Листинг #2 clang Отличия определённых в классе функций и вынесенных из класса функций
#include <iostream>
usingnamespacestd;
classMyClass{
voidfoo1(){//функция всегда inline
//Если тело функции определено в классе
}
voidfoo2();//прототип, функция вне класса
};
inlinevoidMyClass::foo2(){//Такая при необходимости требует явного указания Inline
}
intmain(){
}
Специальные правила для inline функций требуют, чтобы такие функции были определены в каждом файле, в котором используются. Самый простой способ гарантировать, что встроенные определения доступны всем файлам в многофайловой программе — поместить эти определения в тот же заголовочный файл, где объявлен класс.
(Некоторые системы разработки снабжены интеллектуальными компоновщиками, которые разрешают размещать встроенные определения в отдельном файле реализации)
Функции класса, которые делаются inline, должны описываться в той же единице трансляции, в которой объявлен класс.
Если говорить проще, то при написании многофайлового проекта может иметь значение является ли функция класса inline или не является. Здесь как раз может повлиять тот факт, что определённые внутри класса функции по умолчанию inline, а выносимые за пределы класса функции по умолчанию не inline.
inline — это рекомендация компилятору переписать функцию в такой вид, где в коде как бы функции не будет, т. е. разложить в тот вид, каким новички пытаются написать программы, когда понятия не имеют о функциях: запихать всё в main. Но тут не в main, а во все места обращения накопировать такую штуковину. Вообще, инлайнить функции при написании многофайловых проектов надо с большой осторожностью. Обычно пишут, что инлайн может ускорить работу программы, но то, что ускорит — совсем не факт, а вот время компиляции замедлить может здорово. В худшем случае из-за inline замедлится и время компиляции программы (при внесении изменений и перекомпилировании из-за этого) и скорость работы программы.
8 комментариев на «“С++ для начинающих. Определение методов класса вне класса”»
может это такой синтаксис в другой среде.
Но в Visual Studio это работает не так.
Мы типо выводим то, что выводится. Корректно будет так
C++
1
obj1.show_a();
ведь метод show_a() и так выводит данные.
Если нам нужно использовать cout, в Main(), то тогда следует изменить void на int для метода show_a().
//void вообще означает, что эта функция не возвращает значений.
и изменить метод на
C++
1
2
3
4
intMyClass::show_a()//Тип функции Класс::Функция. Описываем функцию show_a()
Здравствуйте. Не могу понять вообще в объектном программировании вот что, может вы объясните. В самом объекте есть данные члены, а коды методов в нём есть?
C++ не чисто объектно-ориентированный язык.
Данные члены — это переменные и константы внутри объекта: атрибуты, свойства, значения и т. п.
Коды методов — это поведение и расчёты.
C++
1
2
3
4
5
6
7
classCar{
intcolor;//Просто переменная является данным класса, членом класса.
voiddrive(){//функция-член класса, она же - метод класса
//какое-то поведение езды
}
}
Коды методов — это коды, определяющие поведение объекту.
Функции-члены классов часто называют методами классов.
может это такой синтаксис в другой среде.
Но в Visual Studio это работает не так.
Мы типо выводим то, что выводится. Корректно будет так
ведь метод show_a() и так выводит данные.
Если нам нужно использовать cout, в Main(), то тогда следует изменить void на int для метода show_a().
//void вообще означает, что эта функция не возвращает значений.
и изменить метод на
вот тогда использовать
корректно.
Спасибо!
Перестал читать, после того, как увидел транслит
[/cpp]cout<<suka<<endl;[/cpp]
А как таким же образом объявить методы для шаблонного класса?
Пример для ввода числа и строки.
У меня была попытка это объяснить Шаблоны классов. Первое знакомство
Здравствуйте. Не могу понять вообще в объектном программировании вот что, может вы объясните. В самом объекте есть данные члены, а коды методов в нём есть?
C++ не чисто объектно-ориентированный язык.
Данные члены — это переменные и константы внутри объекта: атрибуты, свойства, значения и т. п.
Коды методов — это поведение и расчёты.
Коды методов — это коды, определяющие поведение объекту.
Функции-члены классов часто называют методами классов.
Вам это нужно было?