【问题标题】:Passing Initiated Class To Function Without Defining Class?将启动的类传递给函数而不定义类?
【发布时间】:2019-01-06 11:53:45
【问题描述】:

我实际上是在尝试将一个类的已启动实例传递给另一个类的方法,当我尝试 #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 */

我尝试过使用标头保护,但仍然没有运气;(

如果我需要为此添加更多信息,我将不胜感激。

【问题讨论】:

标签: c++ xcode macos oop clang


【解决方案1】:

正如 S.M. 的评论中提到的那样。您似乎误解了头文件的用途和使用方式。

要正确理解它,您需要了解三个概念:

  • 在 C++ 中,所有符号都需要声明定义。区别在于声明告诉编译器符号存在于某处,而定义是符号的实际实现或(实际上)定义。

  • C++ 编译器并不真正处理源文件,而是处理translation units。简而言之,一个翻译单元就是一个包含所有头文件的单一源文件。

  • 构建过程,分多个步骤完成:

    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

那么它应该输出

来自Foo的你好

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-16
    • 1970-01-01
    • 2016-06-14
    • 1970-01-01
    • 2018-01-02
    • 2011-08-06
    • 1970-01-01
    • 2022-01-06
    相关资源
    最近更新 更多