C++ 杂记

C++ 静态成员函数

2017-10-26  本文已影响8人  赵者也

通过将某个函数成员声明为 static,我们将使该函数独立于本类的任何具体对象。从静态函数内引用类成员,必须使用限定名进行(就像使用普通函数访问公有数据成员那样)。

静态成员函数的优点是:即使本类的任何对象都不存在,它们也能存在并被调用。这种情况下,静态成员函数只能使用静态数据成员,因为后者是唯一存在的数据成员。因此,即使我们不能肯定是否有类对象存在,也可以调用类的静态函数成员来检查静态数据成员。这样,我们即可用静态成员函数来确定本类的对象是否已经创建,或者实际创建的数量。

例:static void Afun(int n);

可以通过:

① aBox.Afun(10); //对象调用
②CBox::Afun(10); //类+作用域调用

下面是一个在 Qt 框架下,使用 Qt Creator 实现的一个简单的示例程序,我们可以从中看一下静态成员函数:

#include <QCoreApplication>
#include <QDebug>
#include <QUrl>

class OutputInfo
{
public:
    OutputInfo()
//        : m_printTimes(0) // [TOBY标记] 初始化成员列表的重要性
    {
        s_printTimes++;
        m_printTimes++;
    }
    ~OutputInfo(){
        s_printTimes--;
        m_printTimes--;
    }

    static void s_output() {
        qDebug() << "call static in static output "
                 << s_printTimes << " times print!";

        // 编译出错: 静态成员函数中不能引用非静态成员
//        qDebug() << "call normal in static output "
//                 << m_printTimes << " times print!"; // error
        /*
         * 因为静态成员函数属于整个类,
         * 在类实例化对象之前就已经分配空间了,
         * 而类的非静态成员必须在类实例化对象后才有内存空间,
         * 所以这个调用就出错了,
         * 这就是没有声明变量却去使用它
         */
    }

    void m_output() {
        qDebug() << "call static in normal output "
                 << s_printTimes << " times print!";
        qDebug() << "call normal in normal output "
                 << m_printTimes << " times print!";
    }

private:
    static int s_printTimes;
    int m_printTimes;
};

// 静态成员初始化
int OutputInfo::s_printTimes = 0;

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    OutputInfo::s_output();

    OutputInfo* outputInfo = new OutputInfo;
    // 此调用中我们发现 m_printTimes 会显示乱码,
    // 这也告诉我们,[TOBY标记] 处初始化成员列表的重要性
    // 有了初始化,这个值就是 0,而不是乱码
    outputInfo->m_output();
    outputInfo->s_output();
    delete outputInfo;

    OutputInfo::s_output();

    outputInfo = new OutputInfo;
    // 此调用中我们发现 m_printTimes 会显示乱码,
    // 这也告诉我们,[TOBY标记] 处初始化成员列表的重要性
    // 有了初始化,这个值就是 0,而不是乱码
    outputInfo->m_output();
    outputInfo->s_output();
    delete outputInfo;

    // 我们不调用构造函数,我们是 0
    OutputInfo::s_output();
    OutputInfo::s_output();
    OutputInfo::s_output();

    return a.exec();
}

上面的示例的输出大概是下面这样的:

输出结果

欢迎大家提出宝贵意见,谢谢

上一篇下一篇

猜你喜欢

热点阅读