Подтвердить что ты не робот

Объявление функции внутри или вне класса

Я разработчик JAVA, который пытается изучить С++, но я действительно не знаю, что лучше всего подходит для объявлений стандартных функций.

В классе:

class Clazz
{
 public:
    void Fun1()
    {
        //do something
    }
}

Или снаружи:

class Clazz
{
public:
    void Fun1();
}

Clazz::Fun1(){
    // Do something
}

У меня такое чувство, что второе может быть менее читаемым...

4b9b3361

Ответ 1

C++ является объектно-ориентированным в том смысле, что он поддерживает объектно-ориентированную парадигму разработки программного обеспечения.

Однако, в отличие от Java, C++ не заставляет вас группировать определения функций по классам: стандартный способ объявления функции C++ - просто объявить функцию без какого-либо класса.

Если вместо этого вы говорите об объявлении/определении метода, то стандартным способом является помещение только объявления во включаемый файл (обычно называемый .h или .hpp), а определение - в отдельный файл реализации (обычно называемый .cpp или .cxx)., Я согласен, что это действительно несколько раздражает и требует некоторого дублирования, но именно так, как был разработан язык.

Для быстрых экспериментов и проектов с одним файлом все будет работать... но для более крупных проектов такое разделение практически необходимо.

Примечание. Даже если вы знаете Java, C++ - это совершенно другой язык... и язык, который нельзя выучить экспериментально. Причина в том, что это довольно сложный язык с множеством асимметрий и явно нелогичным выбором, и, самое главное, когда вы совершаете ошибку, в Java нет "ангелов ошибок времени выполнения", которые спасут вас, как в Java... но есть вместо этого " неопределенные демоны поведения ".

Единственный разумный способ узнать C++ - это читать... независимо от того, насколько вы умны, вы никак не можете угадать, что решил комитет (на самом деле, быть умным - иногда даже проблема, потому что правильный ответ нелогичен и является следствием). исторического наследия.)

Просто выберите хорошую книгу или две и прочитайте их от корки до корки.

Ответ 2

Первый определяет вашу функцию-член как встроенную функцию, а второй - нет. Определение функции в этом случае находится в самом заголовке.

Вторая реализация поместит определение функции в файл cpp.

Оба семантически различны, и это не просто вопрос стиля.

Ответ 3

Определение функции лучше вне класса. Таким образом, ваш код может оставаться в безопасности, если потребуется. Файл заголовка должен просто указывать объявления.

Предположим, кто-то хочет использовать ваш код, вы можете просто дать ему файл .h и файл .obj(полученный после компиляции) вашего класса. Он не нуждается в файле .cpp для использования вашего кода.

Таким образом, ваша реализация не будет видна кому-либо еще.

Ответ 4

Метод "Внутри класса" (I) делает то же самое, что и метод "вне класса" (O).

Однако (I) можно использовать, когда класс используется только в одном файле (внутри файла .cpp). (O) используется, когда он находится в файле заголовка. Файлы cpp всегда компилируются. Заголовочные файлы скомпилируются, когда вы используете #include "header.h".

Если вы используете (I) в файле заголовка, функция (Fun1) будет объявляться каждый раз, когда вы включаете #include "header.h". Это может привести к объявлению одной и той же функции несколько раз. Это сложнее скомпилировать и даже привести к ошибкам.

Пример правильного использования:

Файл1: "Clazz.h"

//This file sets up the class with a prototype body. 

class Clazz
{
public:
    void Fun1();//This is a Fun1 Prototype. 
};

Файл2: "Clazz.cpp"

#include "Clazz.h" 
//this file gives Fun1() (prototyped in the header) a body once.

void Clazz::Fun1()
{
    //Do stuff...
}

Файл3: "UseClazz.cpp"

#include "Clazz.h" 
//This file uses Fun1() but does not care where Fun1 was given a body. 

class MyClazz;
MyClazz.Fun1();//This does Fun1, as prototyped in the header.

File4: "AlsoUseClazz.cpp"

#include "Clazz.h" 
//This file uses Fun1() but does not care where Fun1 was given a body. 

class MyClazz2;
MyClazz2.Fun1();//This does Fun1, as prototyped in the header. 

Файл5: "DoNotUseClazzHeader.cpp"

//here we do not include Clazz.h. So this is another scope. 
class Clazz
{
public:
    void Fun1()
    {
         //Do something else...
    }
};

class MyClazz; //this is a totally different thing. 
MyClazz.Fun1(); //this does something else. 

Ответ 5

Функции членов могут быть определены в определении класса или отдельно с использованием оператора разрешения области,::. Определение функции-члена в определении класса объявляет функцию inline, даже если вы не используете спецификатор inline. Таким образом, вы можете определить функцию Volume(), как показано ниже:

class Box
{
  public:

     double length;
     double breadth;    
     double height;     

     double getVolume(void)
     {
        return length * breadth * height;
     }
};

Если вам нравится, вы можете определить одну и ту же функцию вне класса с помощью оператора разрешения области,:: следующим образом

double Box::getVolume(void)
{
   return length * breadth * height;
}

Здесь важна только то, что вам нужно будет использовать имя класса непосредственно перед:: operator. Функция-член будет вызываться с использованием точечного оператора (.) На объекте, где он будет обрабатывать данные, относящиеся к этому объекту, только следующим образом:

Box myBox;           

myBox.getVolume();  

(from: http://www.tutorialspoint.com/cplusplus/cpp_class_member_functions.htm) , оба способа являются законными.

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

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

Ответ 6

Первый должен быть помещен в заголовочный файл (где объявляется объявление класса). Второй может быть где угодно: либо заголовок, либо, как правило, исходный файл. На практике вы можете поместить небольшие функции в объявление класса (которое объявляет их неявно встроенными, хотя это компилятор, который в конечном итоге решает, будут ли они включены или нет). Однако большинство функций имеют объявление в заголовке и реализацию в файле cpp, как в вашем втором примере. И нет, я не вижу причин, почему это было бы менее читаемо. Не говоря уже о том, что вы можете разделить реализацию для типа в нескольких файлах cpp.

Ответ 7

Функция, определенная внутри класса, по умолчанию рассматривается как встроенная функция. Простая причина, по которой вы должны определять свою функцию снаружи:

Конструктор класса проверяет виртуальные функции и инициализирует виртуальный указатель, указывающий на правильную таблицу VTABLE или таблицу виртуальных методов, вызывает конструктор базового класса и инициализирует переменные текущего класса, поэтому он действительно выполняет некоторую работу.

Встроенные функции используются, когда функции не так сложны и позволяют избежать накладных расходов на вызов функции. (Накладные расходы включают в себя скачок и ветвь на аппаратном уровне.) И, как описано выше, конструктор не так просто считать встроенным.