我试图使用静态成员函数访问静态数据成员,以便我可以调用此函数并检索数据成员。目标是增加/减少此静态数据成员以计算程序中存在的对象数。
从作业逐字逐句:
应该提供一个名为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
...
}
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;
}
testComplex.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()被声明为一个类,为什么它说函数的范围不正确?
答案 0 :(得分:4)
我不明白为什么编译器不断给我这个错误:
因为您在成员函数定义中重复了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;
}
答案 1 :(得分:1)
static
关键字只应在class
声明中使用。方法实现应省略static
声明:
int& Complex::getNumObjects(){
return counter;
}
奇怪的是,您已经遵循此规则作为静态成员变量; - )
答案 2 :(得分:0)
您必须跟踪析构函数和构造函数中的对象。此外,您真的希望您的计数器为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
管理的)。