Передача инициированного класса в функцию без определения класса? - PullRequest
0 голосов
/ 06 января 2019

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

/Users/arya/Desktop/Arya/Coding/macOS/xx:xxxx/xx:xxxx/Source/Utility/Process/Main.cpp:4:7: Redefinition of 'Process'

/Users/arya/Desktop/Arya/Coding/macOS/xx:xxxx/xx:xxxx/Main.cpp:1:10: In file included from /Users/arya/Desktop/Arya/Coding/macOS/xx:xxxx/xx:xxxx/    Main.cpp:1:

/Users/arya/Desktop/Arya/Coding/macOS/xx:xxxx/xx:xxxx/Header.hpp:9:10: In file included from /Users/arya/Desktop/Arya/Coding/macOS/xx:xxxx/    xx:xxxx/./Header.hpp:9:

/Users/arya/Desktop/Arya/Coding/macOS/xx:xxxx/xx:xxxx/Source/Utility/Scanner/Main.cpp:1:10: In file included from
/Users/arya/Desktop/Arya/Coding/macOS/xx:xxxx/xx:xxxx/./Source/Utility/Scanner/Main.cpp:1:

/Users/arya/Desktop/Arya/Coding/macOS/xx:xxxx/xx:xxxx/Source/Utility/Scanner/Header.hpp:10:10: In file included from /Users/arya/Desktop/Arya/    Coding/macOS/xx:xxxx/xx:xxxx/./Source/Utility/Scanner/./Header.hpp:10:

/Users/arya/Desktop/Arya/Coding/macOS/xx:xxxx/xx:xxxx/Header.hpp:8:10:'/Users/arya/Desktop/Arya/Coding/macOS/xx:xxxx/xx:xxxx/./Source/Utility/    Scanner/../Process/Main.cpp' included multiple times, additional include site here

/Users/arya/Desktop/Arya/Coding/macOS/xx:xxxx/xx:xxxx/Source/Utility/Scanner/Header.hpp:10:10:'/Users/arya/Desktop/Arya/Coding/macOS/xx:xxxx/    xx:xxxx/./Source/Utility/Scanner

/../Process/Main.cpp' included multiple times, additional include site here
/Users/arya/Desktop/Arya/Coding/macOS/xx:xxxx/xx:xxxx/Source/Utility/Process/Main.cpp:4:7: Unguarded header; consider using #ifdef guards or #pragma once

FirstFile.cpp:

#include "./FirstFile.h"
class SomeClass {
    SomeClass() {
        // Do Stuff
    }
}

FirstFile.h:

#ifndef FIRSTFILE_HEADER_HPP
#define FIRSTFILE_HEADER_HPP

#import <iostream>
// import stuff

#endif /* FIRSTFILE_HEADER_HPP */

SecondFile.cpp:

#include "./SecondFile.h"
class SomeClassTwo {
    SomeClassTwo(Someclass * InitializedClass) {
        InitializedClass -> DoSomething()
    }
}

SecondFile.h:

#ifndef SECONDFILE_HEADER_HPP
#define SECONDFILE_HEADER_HPP

#import "./FirstFile.cpp"
// import stuff

#endif /* SECONDFILE_HEADER_HPP */

Я пытался использовать защиту заголовков, но все же не повезло; (

Буду признателен за любую помощь и сообщу, если мне нужно добавить дополнительную информацию к этому

1 Ответ

0 голосов
/ 07 января 2019

Как уже упоминалось в комментарии С.М. похоже, вы неправильно понимаете, для чего нужны заголовочные файлы и как они используются.

Чтобы правильно понять это, нужно знать три понятия:

  • В C ++ все символы должны быть оба объявлены и определены . Разница в том, что объявление сообщает компилятору, что символ существует где-то , тогда как определение является фактической реализацией или (действительно) определением символа.

  • Компилятор C ++ на самом деле имеет дело не с исходными файлами, а с единицами перевода . Короче говоря, единица перевода - это один исходный файл со всеми включенными заголовочными файлами.

  • Процесс сборки, который выполняется в несколько этапов:

    1. Редактирование исходных и заголовочных файлов
    2. Сборка исходных файлов (единиц перевода) в объектные файлы (каждый объектный файл представляет одну единицу перевода)
    3. Ссылка объектных файлов в конечный исполняемый файл

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

Теперь вернемся к заголовочным файлам и их использованию ...

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

Файлы исходных файлов содержат определение (реализацию) функций, переменных и функций-членов структуры / класса.

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

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


Может потребоваться простой пример.

Заголовочный файл foo.h:

// Header include guard (to prevent multiple inclusion in a single translation unit)
#ifndef FOO_H
#define FOO_H

// Define the class Foo
class Foo
{
public:
    // Declare the function hello
    void hello();
};

// End of the header include guard
#endif

Исходный файл foo.cpp:

// Include the header files we need
#include <iostream>
#include "foo.h"

// Define (implement) the member function
void Foo::hello()
{
    std::cout << "Hello from Foo\n";
}

Заголовочный файл bar.h:

// Header include guard (to prevent multiple inclusion in a single translation unit)
#ifndef BAR_H
#define BAR_H

// We use the Foo class, so need to include the header file where that class is defined
#include "foo.h"

// Define the class Bar
class Bar
{
public:
    // The Bar default constructor, we define it inline
    Bar()
        : my_foo()    // Constructor initializer list, constructs and initializes the member variables
    {
        // Empty body
    }

    // Declare the function my_hello
    void my_hello();

private:
    Foo my_foo;
};

// End of the header include guard
#endif

Исходный файл bar.cpp:

#include "bar.h"

// Define the function
void Bar::my_hello()
{
    // Call function from other class
    my_foo.hello();
}

И чтобы связать все это вместе, файл main.cpp:

// We will use the Bar class, so include the header file where it's defined
#include "bar.h"

int main()
{
    Bar bar;

    bar.my_hello();
}

Для построения этого (при условии, что macOS и компилятор clang++) вы можете использовать следующие команды в терминале (при условии, что исходный и заголовочный файлы находятся в текущем каталоге):

$ clang++ -Wall foo.cpp -c
$ clang++ -Wall bar.cpp -c
$ clang++ -Wall main.cpp -c
$ clang++ foo.o bar.o main.o -o my_example_program

Для опций компилятора:

  • -Wall включить больше предупреждений, что хорошо
  • -c говорит программе внешнего интерфейса компилятора сгенерировать объектный файл из модуля перевода (вместо попытки создания исполняемого файла)
  • -o для имени выходного файла

Если вы запустите программу

$ ./my_example_program

тогда должно получиться

Hello from Foo
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...