【问题标题】:Static private member counter静态私有成员计数器
【发布时间】:2012-11-04 18:26:53
【问题描述】:

更新::

好的,所以我在头文件中有这些新行:

static void gcdStatsCounter();//increments counter
static void display(); // displays the gcdStats
static int gcdStats;//• calls to gcd

public:                                  // interface routines
        static void statistics();              // print statistics

然后我添加到cpp文件中:

int Rationalnumber::gcdStats(0);//initialization

void Rationalnumber::gcdStatsCounter() { // counter incrementer
    gcdStats++;
}

void Rationalnumber::display() {// displays the gcdStats
    cout << "gcdStats = " << Rationalnumber::gcdStats << endl;
}

void statistics() {
    Rationalnumber::display();
}                       // print statistics

它给了我错误:static void Rationalnumber::display() is private。挑战是我只添加私有成员而不触及接口例程:(朋友函数是避免。有什么想法吗?

原帖::

我在更新以下部分下的静态计数器变量时遇到问题://我的成员

规则:“不要更改、添加或删除接口的 GIVEN 代码的成员。如果需要,您可以添加私有成员,但不允许进行其他更改。”

我的问题是如何在不创建新公共函数的情况下更新私有成员?我知道我需要一个静态私有成员函数来访问一个静态私有成员变量。但是,每当我尝试访问静态私有计数器变量时,都会收到错误“未定义的引用...”例如,gcdStats 的这个私有计数器函数(声明为静态)会给我这样的错误:

void Rationalnumber::gcdStatsCounter() {
    gcdStats++;
}

头文件:

#ifndef RATIONALNUMBER_H
#define RATIONALNUMBER_H
#include <iostream>
// HEADER FILE

class Rationalnumber
{
    friend bool operator==( Rationalnumber l, Rationalnumber r );
    friend bool operator!=( Rationalnumber l, Rationalnumber r );
    friend bool operator<( Rationalnumber l, Rationalnumber r );
    friend bool operator<=( Rationalnumber l, Rationalnumber r );
    friend bool operator>( Rationalnumber l, Rationalnumber r );
    friend bool operator>=( Rationalnumber l, Rationalnumber r );

    friend Rationalnumber operator+( Rationalnumber l, Rationalnumber r );
    friend Rationalnumber operator-( Rationalnumber l, Rationalnumber r );
    friend Rationalnumber operator*( Rationalnumber l, Rationalnumber r );
    friend Rationalnumber operator/( Rationalnumber l, Rationalnumber r );

    friend std::istream &operator>>( std::istream &is, Rationalnumber &r );
    friend std::ostream &operator<<( std::ostream &os, Rationalnumber r );

    int num, denom;                        // implementation


    // MY MEMBERS

    // functions
    static int gcd(int n, int d); // for the gcd function
    static void zeroDenom(); // is called whenever denom = 0

    // variables
    // object stats:
    // The first four statistics vary depending on the implementation approach
    static void gcdStatsCounter();
    static int gcdStats;//• calls to gcd
    static int con;     //• rational-number objects created by regular constructors
    static int copy;    //• rational-number objects created by copy constructor
    static int des;     //• rational-number objects destroyed by destructor

    //operation stats:
    // must be consistent across implementations
    static int assn;    //• assignments to rational-number objects
    static int rel;     //• relational/equality operations between rational-number objects
    static int add;     //• addition/subtraction operations between rational-number objects
    static int sub;
    static int mul;     //• multiplication/division operations between rational-number objects
    static int div;
    static int in;      //• input/output operations on rational-number objects
    static int out;


  public:                                  // interface routines
    Rationalnumber();
    Rationalnumber( int n );
    Rationalnumber( int n, int d );
    Rationalnumber( const Rationalnumber &c ); // copy constructor
    ~Rationalnumber();

    int numerator() const;                 // return numerator
    int numerator( int n );                // set numerator to n; return previous numerator
    int denominator() const;               // return denominator
    int denominator( int d );              // set denominator to d; return previous denominator

    Rationalnumber operator-();            // unary negation
    Rationalnumber &operator=( const Rationalnumber &r ); // assignment

    static void statistics();              // print statistics

}; // Rationalnumber

#endif // __RATIONALNUMBER_H__

更新::查看顶部

【问题讨论】:

  • 是的,但只是想确保您理解这一点。非静态成员函数也可以访问静态成员。但是静态成员函数不能访问非静态成员。
  • 定义void statistics() {...} 不是类成员,因此与您在标题中声明的静态成员的功能不同。这是一个错误吗?
  • @aschepler 它是公共类成员。它在原始代码的最底部声明。
  • 您声明了void Rationalnumber::statistics(),但定义了void statistics()。 C++ 考虑了这两个不同的函数(第二个没有访问Rationalnumber 私有成员的权限)。
  • 该死!这不是第一次发生在我身上!现在可以了!!!谢谢!!

标签: c++ private-members


【解决方案1】:

这是给学校的吗?

也许您的老师希望您发现 friend 关键字。

【讨论】:

  • 实际上,从技术上讲,显然不需要使用友元函数...还有其他方法来更新静态计数器变量吗?
【解决方案2】:

你只声明了你的静态成员,你还没有定义它们。

一般用静态变量,需要在类定义里面声明,然后在外面定义,例如:

class Rationalnumber
{

    static float f;
    //...

};

编辑:当然,定义应该放在 .cpp 文件中,而不是放在头文件中。这样做的原因是为了避免多个定义,如果您的头文件包含在多个源文件中,就会发生这种情况。链接器的任务是初始化静态对象,下面的几行基本上告诉链接器它存在以及如何处理它。

//In Rationalnumber.cpp:
float Rationalnumber::f; //Allow default initialization
float Rationalnumber::f(5.0); //Initialize with non-default value

【讨论】:

  • 如果没有设置,显然 C++ 默认将它们设置为零?
  • @jonathan 它会默认构造它,但实际上是链接器抱怨它看不到它,而不是编译器。
  • @jonathan:如果您不将静态变量初始化为其他值,它们将被初始化为零。但是它们仍然需要在源文件中定义 - 你没有这样做,因此会出现错误。
  • 好的,既然我定义了它,它就在抱怨一个随机的朋友函数,operator==: "multiple definition of Rationalnumber::gcdStats" 首先定义在这里
  • 哦,好的,等等,既然您说要放入 .cpp,它就不再抱怨了!让我们看看我是否可以更进一步......
【解决方案3】:

在标题中声明你的静态方法:

静态 void gcdStatsCounter();

【讨论】:

  • 原始代码包含它,很抱歉误导:/
猜你喜欢
  • 2020-03-22
  • 2014-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-24
  • 1970-01-01
相关资源
最近更新 更多