【问题标题】:making static variables in member functions independent for each instance使成员函数中的静态变量独立于每个实例
【发布时间】:2019-07-29 14:30:46
【问题描述】:

给定班级:

class A {
    Public:
        void foo() {
            static int i;
            i++;
        }
};

您将如何更改它以防止 i 在此示例之后的实例之间更改:

A o1, o2, o3;
o1.foo(); // i = 1
o2.foo(); // i = 1
o3.foo(); // i = 1
o1.foo(); // i = 2

即在每个实例上为 i 分配内存。

编辑:

是的,您可以添加i 作为实例变量,但是如果您需要在各种(独立)函数中使用这些计数器怎么办?我希望将变量的范围仅限于函数(“在成员函数中”)。如果需要各种计数器,在类中添加iccountercounter_2 等变量似乎很尴尬,不是吗?

【问题讨论】:

  • .... 这就是 instance 变量的用途
  • static 变量是您想要唯一实例时所做的事情。如果您想保留 class 的每个实例的状态,则需要将该状态存储为 class 的成员。
  • 赞成。这个问题很奇怪,但不一定很差。
  • 想一想如果这确实按您希望的方式工作会发生什么:成员内部的“静态”变量必须存储在对象实例的一部分中才能特定于实例,但是在 C++ 中,您通常将类与成员实现分开声明,并且类声明必须足以让编译器计算对象的大小。由于“静态”变量是在方法内部而不是在类定义中声明的,因此只能看到定义的代码不知道它的大小。因此,我们有一个矛盾,这不能那样工作。

标签: c++ function class static member


【解决方案1】:
class A
{
public:
    int i = 0;
    void foo(){
        ++i;
    }
};

是正常的方式:i 现在是类的成员变量。显然你不想使用static

【讨论】:

  • 我会将i设为私有
【解决方案2】:

在声明数据成员变得昂贵的情况下(需要不经常使用的稀疏成员),实例独立集合 - 通常是关联集合 - 可能会派上用场。对 OP 的意图一无所知,std::map 类家族可以用作第一个推测。我们需要在A::foo 中为每个访问过的对象设置一个计数器,但对于未访问的实例(即A 未调用A::foo 的实例)则不需要。这是我想出的最简单的第一个解决方案:

void A::foo(){
    static std::map<A*,std::size_t> i;
    ++i[this];
    //...
};

在对不在映射中的对象调用std::map::operator[] 时,关联值默认构造在已由分配器归零的内存位置(简而言之,第一个定时器会自动初始化为 0)。

【讨论】:

  • @RamGhadiyaram 职业选手讨厌打字?
  • 点个赞。这有一种优雅,这在 OP 的编辑之后尤其相关。考虑const A* 虽然是关键?当然,如果有很多A 的实例化和foo 的后续调用,则映射可能会变得很大。但这是可以解决的,尽管我认为开销与更简单方法的单独类成员相当。
  • @Bathsheba 同意了。但是关联容器旨在实现稀疏矩阵。此外,我只是暗示'std :: map'的接口。但同样,任何类似的方法仅在与“A”实例的数量相比很少使用“A::foo”时才有用
猜你喜欢
  • 2022-08-09
  • 1970-01-01
  • 2011-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多