使用静态成员函数访问静态数据成员

Using Static Member Function to Access Static Data Member

我正在尝试使用静态成员函数访问静态数据成员,以便我可以调用此函数并检索数据成员。目标是increase/decrease这个静态数据成员来统计程序中存在多少个对象。

作业逐字记录:

A static member function called getNumObjects should be provided that takes no parameters and returns an int indicating the number of objects of type Complex currently in existence.

到目前为止我的代码:

Complex.hpp

class Complex{
public:
...
// Get the number of complex objects in the current program
        static int& getNumObjects();
...

private:
...
        static int counter; // static counter
...
}

Complex.cpp

// Initialize object counter for getNumObjects()
int Complex::counter = 0;
// Get number of objects existing in the current program
static int& Complex::getNumObjects(){
        return counter;
}

测试Complex.cpp

// checks to see how many complex objects are open currently
        std::cout << "How many complex objecst are in existence? ";
        int num = Complex::getNumObjects();
        std::cout << num << '\n';
        std::cout << "successful\n";

我不明白为什么编译器总是向我抛出这个错误:

 error: cannot declare member function ‘static int& Complex::getNumObjects()’ to have static linkage [-fpermissive]
 static int& Complex::getNumObjects(){

或此错误:

In function ‘int getNumObjects()’:
/../../../ error: ‘counter’ was not declared in this scope
  return counter;
         ^~~~~~~
/../../../ note: suggested alternative: ‘toupper’
  return counter;
         ^~~~~~~
         toupper

我进行了广泛的搜索,我似乎已经很好地初始化了我的私有数据成员以及函数。 getNumObjects() 表示为 class,那么为什么说函数的范围不正确?

static 关键字只能在 class 声明中使用。方法实现应省略 static 声明:

int& Complex::getNumObjects(){
        return counter;
}

奇怪的是,您已经为您的静态成员变量遵循了这条规则;-)

I don't understand why the compiler keeps throwing me this error:

因为你在成员函数定义中重复了static。该函数已声明 static; C++ 语法要求您在 cpp 文件中省略 static

int Complex::counter = 0;
// Get number of objects existing in the current program
int& Complex::getNumObjects(){
    return counter;
}

注意: return int& 可能不是一个好主意,因为调用者可以修改 counter 而不是你的知识:

Complex::getNumObjects() = -123; // <<== returning reference makes this legal

这非常糟糕,因为它完全破坏了封装。本质上,您的 counter 最终被公开,就好像它是一个 public 成员变量一样。

您应该将函数更改为 return int

int Complex::getNumObjects(){
    return counter;
}

您绝对必须跟踪析构函数和构造函数中的对象。此外,您真的希望您的计数器达到 atomic,以便在多个线程上 运行 时不会出现竞争条件。

struct Complex
{
  Complex()
  { ++counter; }

  Complex(Complex const&other)
  : _real(other._real), _imag(other._imag)
  { ++counter; }

  Complex(double r, double i=0)
  : _real(r), _imag(i)
  { ++counter; }

  // and so on for all other constructors

  Complex&operator=(Complex const&) = default;

  Complex&operator=(double x)
  {
    _real = x;
    _imag = 0;
    return *this;
  }

 ~Complex() { --counter; }

  static int getNumObjects() { return counter; }

private:
  double _real,_imag;
  static std::atomic<int> counter;
};

实际上并不需要移动构造函数(因为堆上的数据不由 Complex 管理)。