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

Using Static Member Function to Access Static Data Member

本文关键字:静态 数据成员 访问 函数 静态成员      更新时间:2023-10-16

我正在尝试使用静态成员函数访问静态数据成员,以便我可以调用此函数并检索数据成员。目标是增加/减少此静态数据成员,以计算程序中存在多少对象。

作业逐字记录:

应提供一个名为 getNumObjects 的静态成员函数,该函数不带任何参数,并返回一个 int,指示当前存在的 Complex 类型的对象数。

到目前为止我的代码:

Complex.hpp

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

复杂.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;
}

测试复杂.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 << "successfuln";

我不明白为什么编译器一直给我这个错误:

 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(( 被声明为一个类,那么为什么它说函数的作用域不正确呢?

我不明白为什么编译器一直给我这个错误:

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

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

注意:返回int&可能不是一个好主意,因为调用者可以在您不知情的情况下修改counter

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

这是非常糟糕的,因为它完全破坏了封装。从本质上讲,您的counter最终会像公共成员变量一样公开。

您应该更改函数以返回int

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

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

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管理(。