【问题标题】:Static Functions and class variables?静态函数和类变量?
【发布时间】:2015-05-20 10:45:25
【问题描述】:

我已将我的问题分解为一个简单的小程序。

我有一个类myclass 我在一个单独的.cpp 文件“classes.cpp”中创建并在头文件“classes.h”中声明。 myclass 包含一个变量a,它在实例化时被初始化。这使得变量a = 5

我的总体目标是在 .h 文件中声明的单独 .cpp 文件中创建一个类,我可以在我的 main() 程序中创建多个实例。我遇到的问题是这样的。

在我的main() 函数中,我创建了一个名为firstmyclass 实例。 我的主程序显示变量 a 设置为数字 5。 如果我想使用静态函数更改该数字(并且它必须是静态函数,因为这与我正在编写的另一个程序中更大的东西有关)。我直接调用静态函数并在该静态函数中创建myclass 的实例并调用非静态函数,因为静态函数没有将它们连接到对象的隐式“this”。

在我的 non_static_function 中,我将值更改为数字 8。问题是当我希望它为 8 时,“first”中的变量“a”的值保持为 5。我需要使用 @987654331 更改值@ 而不是 first->a = 8。 .我该怎么做?

代码如下:

**main.cpp**
#include <iostream>
#include "classes.h"

using namespace std;

int main()
{

    myclass *first = new myclass();
    cout << "Myclass variable a is = " << first->a << endl;

    first->static_function(8); // trying to change myclass variable 'a' to 8.

    cout << "But" << endl;
    cout << "the actual value of a is still: " << first->a << endl;
}

**classes.h**
#ifndef CLASSES_H_INCLUDED
#define CLASSES_H_INCLUDED
class myclass
{
public:
    int a;
    myclass();

    void non_static_function(int x);
    static void static_function(int x);

};
#endif // CLASSES_H_INCLUDED

**classes.cpp**
#include <iostream>
#include <cstdlib>
#include "classes.h"

using namespace std;

myclass::myclass()
{
    a = 5;
}

void myclass::non_static_function(int x)
{
    a = x;
    cout << "The value for variable 'a' was 5 but is now: " << a << endl;
}

void myclass::static_function(int x)
{
    myclass *p = new myclass();
    p->non_static_function(x);
}

【问题讨论】:

  • 不能用静态方法改变非静态字段,除非传入要改变的实例(first)。
  • 这就是为什么您在静态函数中创建该对象的实例并调用非静态函数的原因。据我所知,non_static_function 应该能够更改类值(而且我不确定为什么它不会反映在“first”实例中。
  • p in static_function 在函数结束时立即超出范围,因此不会影响任何内容。请记住,在static_function 中创建的p 与您创建的任何其他实例完全分开,例如first。更改有关 p 的任何内容将对 first 产生 0 影响。小心使用new,你不应该像现在这样使用它。你永远不会在它上面调用 delete,所以它永远不会释放你请求的空间(这不会像在 java 中那样自动发生)。作为一般规则,你真的不应该在构造函数之外使用new
  • 如果您希望 a 可以从任何地方修改,您应该将其设为静态字段,而不是实例字段。
  • “改变任何关于 p 的东西都会对第一个产生 0 影响。”。我认为这是关键点。但是 p 只是在那里调用一个非静态函数(我不在乎它是如何实例化的)。我只需要定义 non_static_function 来更改类值。从输出中可以看出,肯定会调用 non_static_function。但是,我认为您已经提出了如上所述的关键点。那么...有没有办法为“myclass”的所有实例更改变量“a”?

标签: c++ function static


【解决方案1】:

如果您希望myclass 的每个实例都有自己的a,并且您想调用静态函数来更改它,那么您需要将要更改的实例传递给静态函数。静态函数只能修改类的静态成员或在其范围内的实例的成员。非静态成员函数可以更改任何属于该类成员的变量。

class Foo
{
private:
    int bar;
public:
    static void static_function(int value, Foo & foo) { foo.bar = value; }
    void non_static_function(int value) { bar = value; }
};

int main()
{
    Foo foo;
    Foo::static_function(8, foo);
    // now bar will have the value of 8
    foo.non_static_function(20);
    // now bar will have the value of 20
}

【讨论】:

  • 似乎他需要a 本身是静态的;虽然我不确定这是最好的设计选择。
  • @KarolyHorvath 我同意 OP 不应该这样做,但我想展示他们在需要时如何做。
  • 仍然是一个好点内森。现在,如果我不从 main() 调用我的静态函数怎么办。如果该调用是从单独的 .cpp 文件中的另一个类发出的怎么办?我需要以某种方式获取我在 main() 中实例化的实例并在另一个类的定义中使用它来更改“myclass”中的值?
  • @Svetsi 您必须以某种方式将实例传递给它。静态函数如何知道要更改哪个实例?您可以让其他类获取指向实例的共享指针,也可以让它获取引用。
【解决方案2】:

我终于找到了解决这个小问题的方法。在 classes.cpp 中的“myclass”定义之上,我声明了一个“myclass”变量 我的班级 *tgt; 。然后在“myclass”的构造函数中,我只是将实例化的对象分配给我的全局 myclass 变量,我可以从 myclass 定义 tgt = this; 访问它现在我可以在我的静态函数中使用 tgt在我的 'myclass' 定义中调用 non_static_function 并且一切正常。

NathanOliver,你说我需要一个类实例是正确的,但我在这里完成的方式适合我的需要。传递 myclass 的实例当然是另一种方法,但它需要一个高于我的“myclass”定义的全局函数。

感谢您的帮助。

    **main.cpp**
    #include <iostream>
    #include "classes.h"

    using namespace std;

    int main()
    {

         myclass *first = new myclass();
 cout << "Myclass variable a is = " << first->a << endl;

 first->non_static_function(8); // trying to change myclass variable 'a' to 8.

cout << "But" << endl;
cout << "The actual value of a is still: " << first->a << endl;

myclass *second = new myclass();
cout << "For the 'second' class the variable a is: " << second->a << endl;
second->non_static_function(23);
cout << "After calling the static function from 'second' the value of a is: " << second->a << endl;
cout << "And first->a is still: " << first->a << endl;
    }



    **classes.h**
    #ifndef CLASSES_H_INCLUDED
    #define CLASSES_H_INCLUDED
    class myclass
    {
    public:
        int a;
        myclass();

        void non_static_function(int x);
        static void static_function(int x);

    };
    #endif // CLASSES_H_INCLUDED





    **classes.cpp**
    #include <iostream>
    #include <cstdlib>
    #include "classes.h"

    using namespace std;

    myclass *tgt;  // *Add a global myclass variable above the myclass 
      definition*

    myclass::myclass()
    {
       tgt = this;  // *In the constructor allocate the instantiated class
   //from main() to "tgt" .*
        a = 5;
    }

    void myclass::non_static_function(int x)
    {
        a = x;
    // Now see that the value of a is changed.
   cout << "The value for variable 'a' was 5 but is now: "<< this->a << endl;
    }

    void myclass::static_function(int x)
    {
        tgt->non_static_function(x);
    }

【讨论】:

  • 实际上,我承认我的解决方案只能解决部分问题。如果我创建 myclass 的多个实例,则两个实例的功能在某些情况下会发生冲突。因此,我的问题正在演变。有谁知道如何跟踪 myclass 的多个实例,以便当我访问每个实例时,更改只发生在我访问过的类中?我在想一个静态计数器和一个矢量或地图,但我不确定。必须有一个标准的方法来做到这一点?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-30
  • 1970-01-01
  • 2016-07-26
  • 1970-01-01
  • 2015-06-20
  • 1970-01-01
相关资源
最近更新 更多