2014-02-06 2 views
-3

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

app_core.cpp: (здесь мы имеем класс)

class s1 
{ 
    private: 
     int gx; 

    public: 
     int gx(int x,int y) 
     { 
      gx = x; 
     } 
}; 

app1.cpp: (здесь мы используем класс)

#include "app_core.cpp" 
class s1; 

int show() 
{ 
    s1 new_s; 
    cout << new_s.gx(8, 7); 
} 

app2.cpp: (здесь мы используем класс)

#include "app_core.cpp" 
class s1; 

int show() 
{ 
    s1 new_s; 
    cout << new_s.gx(18, 17); 
} 

Как архивировать что-то вроде выше?

+4

Почему бы не использовать заголовки? – JBL

+0

Это хорошая практика, но это не решает мою проблему. – JoeFrom

+0

никогда не включают файлы .cpp с командой 'include <>' – deW1

ответ

2

В C++, когда вы # включаете что-то, включенный файл более или менее «вставлен» вместо этой директивы.

Существует концепция под номером единица перевода, которая указывает блок кода, который компилируется и может в будущем ссылаться на другие блоки (при времени соединения).

Вы хотите написать блок перевода и предоставить другим единицам перевода информацию о том, как получить доступ к этим данным. Такова цель файла .

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

Файл s1class.h

class s1 
{ 
    private: 
     int gxd; 

    public: 
     int gx(int x,int y) 
     { 
      gxd = x; 
      return x; 
     } 
}; 

и

App1. каст:

#include"s1class.h" 

//... use s1 class 

app2.cpp:

#include"s1class.h" 

//... use s1 class 

Просто заметить одну вещь: вы должны никогда нарушают One Definition Rule, вы можете объявить столько раз, сколько вы хотите что-то (до тех пор, пока они последовательные заявления), но вы не можете определить более, чем один раз символ (например, функция). (маленькое примечание: #pragma однажды директивы и подобные вещи могут помочь вам избежать повторного объявления символов более одного раза и сделать вашу жизнь проще, если включить заголовок несколько раз в нескольких местах).

Таким образом, в приведенном выше коде функция «gx» определена в файле заголовка. Эта функция должна существовать только один раз на единицу перевода, где она используется.

В этом конкретном случае он используется для создания единиц перевода для app1.cpp и app2.cpp. Это должно нарушить ОДР, не так ли? Это не будет, так как функция-член для класса неявно встроена в, что означает, что она «сшита» в тело вызывающего абонента, тем самым интегрируя часть идентификатора вызывающего.

Альтернативой является только объявить вещи в файле заголовка и реализовать их в связанном файле CPP:

s1class.ч

#pragma once 

class s1 
{ 
private: 
    int gxd; 

public: 
    int gx(int x,int y); 
}; 

s1class.cpp

#include "s1class.h" 

int s1::gx(int x,int y) 
{ 
    gxd = x; 
    return x; 
} 

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

+0

Есть ли недостаток с использованием 1-го примера? – JoeFrom

+0

Когда «inlining» всегда есть преимущество и недостаток: http://stackoverflow.com/a/145841/1938163. Подводя итог, вы не уверены в правильности функции, но у компилятора будет окончательное решение. Вы просто отмечаете его как «встроенный». Если он будет вставлен, код будет быстрее (поскольку вам не нужно вызывать функцию, вы просто выполняете что-то сразу), но она также будет увеличиваться в размере (более избыточный код вместо функции в одном месте). Обычно вы отмечаете встроенные функции, когда у вас есть небольшие критически важные для вас методы. –

+0

Последний вопрос: зачем использовать пример 2, когда вы можете использовать пример 1, учитывая, что размер файла не является проблемой? Я имею в виду, что пример 2 более сложный и требует много времени для работы? – JoeFrom

1

Вы можете использовать заголовки. app1.h:

class s1 
{ 
    private: 
     int gx; 

    public: 
     int gx(int x,int y) 
     { 
      gx = x; 
     } 
}; 

app2.cpp:

#include"app1.h" 
//... 

также файл app1.h должен быть с скомпилированный файл
или же добавить адрес как

#include "D:\app1.h" 
//... 

если ваш файл app1.h находится в D: привод

0

Firs t, очень плохой стиль для включения файла cpp. Теоретически вы можете написать весь код из app_core.cpp в заголовок, например app_core.h. Хотя это работает в большинстве случаев, это может привести к излишне длительному времени компиляции. Если вы действительно хотите это сделать, вы должны оставить class s1; из обоих файлов .cpp.

Если разделение между заголовком и источником - это то, что вы имели в виду под «грязным кодом», тогда мне жаль, но нет, нет общего способа добиться этого.

+0

За исключением медленной компиляции, какой недостаток. В теории вы могли бы написать весь код из app_core.cpp в заголовок, например app_core.h'? – JoeFrom

+0

Это основной недостаток. Кроме того, все функции, определенные внутри тела класса, будут неявно объявлены как 'inline', но это не должно быть проблемой. Это всего лишь подсказка для компилятора. Но у вас возникнут проблемы с попыткой определить статическую переменную-член таким образом, потому что она в основном должна быть объявлена ​​в файле .cpp, чтобы компилятор и компоновщик знали, где определен один экземпляр этой переменной. – anderas

0

Создайте файл заголовка.

app1.h

class s1 
{ 
    private: 
     int gx; 

    public: 
     int gx(int x,int y) 
}; 

app1.cpp

#include "app1.h" 

int s1::gx(int x,int y) 
{ 
    gx = x; 
} 

app2.cpp

#include "app1.h" 
// your code that calls s1 methods 
0

Я думаю, что это может решить "проблему": поставить свой класс в заголовке , и реализовать его в заголовке (это называется, например, для библиотек «только для заголовка»).

#ifndef CLASS1_H 
#define CLASS1_H 

class s1 
{ 
    private: 
     int gx; 

    public: 
     int gx(int x,int y) 
     { 
      gx = x; 
     } 
}; 
#endif //CLASS1_H 

Затем в каждый раз #include "Class1.h" нужен .cpp.

Там один класс в одном файле (без разделения декларации и реализации).Только обратите внимание, что в то время как иногда удобно, используя «заголовок только» код имеет свои недостатки:

  • Реализация теперь привязана к декларации, что означает, что любое изменение в реализации будет означать, что вы должны повторно скомпилируйте код, который включает этот заголовок.

  • Компиляция займет больше времени, поскольку блок компиляции должен видеть все реализации в блоке трансляции, а не только интерфейсы.

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

Смежные вопросы