【问题标题】:How to make a variable available to multiple .cpp files using a class?如何使用类使变量可用于多个 .cpp 文件?
【发布时间】:2015-09-23 04:21:57
【问题描述】:

这个问题来源于this one

我有一个必须分成多个部分的工作程序。在这个程序中,需要在程序的某些部分中多次使用一个变量(现在它是一个 GTK+ 一个:P),这些变量最终会出现在单独的 .cpp 文件中。

所以,我做了一个简单的例子来了解如何使变量可用于程序部分。先前代码的修改版本将是:

#include <iostream>

using namespace std;

int entero = 10;

void function()
    {
    cout<<entero<<endl;
    //action1...;
    }

void separated_function()
    {
    cout<<entero<<endl;
    //action2...;
    }

int main( int argc, char *argv[] )
    {
    function();
    separated_function();
    cout<<entero<<endl;
    //something else with the mentioned variables...;
    return 0;
    }

需要正确拆分代码,将function()another_function()main() 放在单独的.cpp 文件中,并使entero 可供所有人使用... 但是:

在上一个问题@NeilKirk评论道:Do not use global variables. Put the required state into a struct or class, and pass it to functions as necessary as a parameter(而且我也发现很多网页指向不建议使用全局变量)。

据我所知,在@PaulH. 提供的答案中,他描述了如何通过使变量全局化来使变量可用。 这个答案非常有用,它不仅适用于 char 数组,而且适用于 ints、strings 和 GTK+ 变量(或指向变量的指针:P)。

但是由于不推荐使用这种方法,我会感谢任何能够展示将变量作为函数参数传递的代码的正确方法或比工作全局变量更推荐的其他方法的人。

我研究了参数和类,但是我是新手,我把代码弄乱了,没有好的结果。

【问题讨论】:

  • 您知道您可以创建自己的自己的头文件,并将它们包含在多个源文件中吗?头文件可以包含声明和类或结构定义。
  • 是的,但是这个文件的目的是将它们编译在一起,并且在所有这些文件中包含相同的变量会在编译时生成多重定义。而且我真的不明白如何制作您所说的内容,我尝试过但失败了。

标签: c++ class struct scope


【解决方案1】:

如果您想要与全局变量相同的功能,则需要提供参数作为参考

#include <iostream>

using namespace std;


// renamed the parameter to avoid confusion ('entero' is valid though) 
void function(int &ent)
{
    cout<<ent<<endl;
    ++ent; // modify its value
    //action1...;
}

void separated_function(int &ent)
{
    cout<<ent<<endl;
    ++ent; // modify its value again
    //action2...;
}

int main( int argc, char *argv[] )
{
    int entero = 10; // initializing the variable

    // give the parameter by reference => the functions will be able to modify its value
    function(entero);
    separated_function(entero);

    cout<<entero<<endl;
    //something else with the mentioned variables...;
    return 0;
}

输出:

10
11
12

【讨论】:

  • 该变量在包括main()在内的所有函数中都应该是相同的,即使值可能会改变。问题是它应该在哪里声明、定义以及如何将它传递给函数。
  • @Fahedsl 通过引用传递变量,它在包括main()在内的所有函数中都是相同的。答案确实展示了如何声明、定义变量并将其传递给函数。
  • @Zermingore 。 +1。好的,我试过了,现在我明白了,非常感谢你的回答。 :)
【解决方案2】:

在头文件中定义类或结构是可行的方法,然后将头文件包含在需要类或结构的所有源文件中。如果多个源文件以及变量声明(例如extern int some_int_var;)和namespace声明需要,您还可以将函数原型或预处理器宏放在头文件中。

定义类不会出现多个定义错误,因为类是编译器要处理的概念,类本身永远不会传递给发生多个定义错误的链接器。


举个简单的例子,一个头文件,两个源文件。

首先是头文件,例如myheader.h:

#ifndef MYHEADER_H
#define MYHEADER_H
// The above is called include guards (https://en.wikipedia.org/wiki/Include_guard)
// and are used to protect the header file from being included
// by the same source file twice

// Define a namespace
namespace foo
{
    // Define a class
    class my_class
    {
    public:
        my_class(int val)
            : value_(val)
        {}

        int get_value() const
        {
            return value_;
        }

        void set_value(const int val)
        {
            value_ = val;
        }

    private:
        int value_;
    };

    // Declare a function prototype
    void bar(my_class& v);
}

#endif // MYHEADER_H

上面的头文件定义了一个命名空间foo,在命名空间中定义了一个类my_class和一个函数bar

(命名空间对于像这样的简单程序严格来说不是必需的,但对于较大的项目,它变得更加需要。)

然后是第一个源文件,例如main.cpp:

#include <iostream>
#include "myheader.h"  // Include our own header file

int main()
{
    using namespace foo;

    my_class my_object(123);  // Create an instance of the class

    bar(my_object);  // Call the function

    std::cout << "In main(), value is " << my_object.get_value() << '\n';

    // All done
}

最后是第二个源文件,例如bar.cpp:

#include <iostream>
#include "myheader.h"

void foo::bar(foo::my_class& val)
{
    std::cout << "In foo::bar(), value is " << val.get_value() << '\n';
    val.set_value(456);
}

将所有三个文件放在同一个项目中,然后构建。你现在应该得到一个输出的可执行程序

在 foo::bar() 中,值为 123 在 main() 中,值为 456

【讨论】:

  • +1。感谢您的回答,我花了一点时间来理解它,因为我是新手(:D)。现在我明白了,对我帮助很大。
【解决方案3】:

我更喜欢为全局数据提供功能接口。

.h 文件:

extern int get_entero();
extern void set_entero(int v);

.cpp 文件:

static int entero = 10;

int get_entero()
{
   return entero;
}

void set_entero(int v)
{
   entero = v;
}

然后,在其他任何地方,使用这些功能。

#include "the_h_file"

void function()
{
    cout << get_entero() << endl;
    //action1...;
}

void separated_function()
{
    cout << get_entero() << endl;
    //action2...;
}

int main( int argc, char *argv[] )
{
    function();
    separated_function();
    cout<< get_entero() <<endl;
    //something else with the mentioned variables...;
    return 0;
}

【讨论】:

  • 为什么要声明函数extern?他们默认有外部链接吧?
  • @ChrisDrew,是的,他们有。这是一种风格偏好。它是externstatic。使其显式使代码库保持一致。
【解决方案4】:

如果您不打算修改变量,通常可以将其设为全局。但是,最好使用 const 关键字声明它,以向编译器发出不应修改它的信号,如下所示:

const int ENTERO = 10;

如果您使用多个 cpp 文件,还可以考虑为结构和函数声明使用头文件。

如果您打算修改变量,只需在函数参数中传递它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-18
    • 1970-01-01
    • 1970-01-01
    • 2018-12-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多