当前位置: 首页 > article >正文

C++类的静态成员详解:成员函数非静态成员函数的非法调用

        在C++中,静态成员是属于整个类的而不是某个对象,静态成员变量只存储一份供所有对象共用。所以在所有对象中都可以共享它。使用静态成员变量实现多个对象之间的数据共享不会破坏隐藏的原则,保证了安全性还可以节省内存。

静态成员的定义或声明要加个关键static。静态成员可通过双冒号来使用<类名>::<静态成员名>。

        在C++中类的静态成员变量和静态成员函数是个容易出错的地方,本文先通过几个例子来总结静态成员变量和成员函数使用规则,再给出一个实例来加深印象。希望阅读本文可以使读者对类的静态成员变量和成员函数有更为深刻的认识。

例1:

class Point{
public:
void init(){
//...
    }

static void output(){
//...
    }
};

int main(){
    Point::init();    //作用域调用非静态成员函数
    Point::output();    //作用域调用静态成员函数
    return 0;
}

编译出错:error C2352: 'Point::init' : illegal call of non-static member function

结论1:不能通过类名来调用类的非静态成员函数。

正确写法为以下代码:

class Point {
public:
	void init() {
		//...
	}
	static void output() {
			//...
		}
};

	int main() {
		Point p1;        //实例化对象
		p1.output();     //只能通过对象调用非静态函数

		Point::output();    //作用域调用静态成员函数
		return 0;
		}

编译通过。

结论2:类的对象可以使用静态成员函数和非静态成员函数。

例2:

#include <stdio.h>
class Point{
    public:
        void init(){}
        static void output(){
            printf("%d ", m_x);        //err
                            }
    private:
        int m_x;
    };

int main()
    Point pt;
    pt.output();
    return 0;
}

        编译出错:error C2597: illegal reference to data member 'Point::m_x' in a static member function

        因为静态成员函数属于整个类,在类实例化对象之前就已经分配空间了,而类的非静态成员必须在类实例化对象后才有内存空间,所以这个调用就出错了,就好比没有声明一个变量却提前使用它一样。

结论3:静态成员函数中不能引用非静态成员。

例3:

class Point{
    public:
        void init(){
            output();
        }
        static void output(){}
};

int main(){
    Point pt;
    pt.output();
    return 0;
    }

编译通过。

结论4:类的非静态成员函数可以调用用静态成员函数,但反之不能。

例4:

class Point{
    public:
        Point(){
            m_nPointCount++;
               }
        ~Point(){
            m_nPointCount--;
                }
        static void output(){
            printf("%d ", m_nPointCount);
                }
    private:
        static int m_nPointCount;
};

int main(){
    Point pt;
    pt.output();
    return 0;        
}

编译错误!

        这是因为类的静态成员变量在使用前必须先初始化。在main()函数前加Point::m_nPointCount = 0;  再编译链接无错误,运行程序将输出1。

改正:

class Point {
public:
	Point() {
		m_nPointCount++;
	}
	~Point() {
		m_nPointCount--;
	}
	static void output() {
		printf("%d ", m_nPointCount);
	}
private:
	static int m_nPointCount;

};
//类静态成员变量初始化赋值
int Point:: m_nPointCount = 0;

int main() {
	Point pt;
	pt.output();
	return 0;
}

编译+运行通过

结论5:类的静态成员变量必须先初始化再使用。

总结:

结论1:不能通过类名来调用类的非静态成员函数。

结论2:类的对象可以使用静态成员函数和非静态成员函数。

结论3:静态成员函数中不能引用非静态成员。

结论4:类的非静态成员函数可以调用用静态成员函数,但反之不能。

结论5:类的静态成员变量必须先初始化再使用。

 


http://www.kler.cn/a/17639.html

相关文章:

  • uni-app之数据驱动的picker选择器( uni-data-picker)之可以选择到任意级别
  • 【JAVA基础】JVM是什么?
  • git配置远程仓库的认证信息
  • MySQL的SQL书写顺序和执行顺序
  • Zotero 6.0 安装包及安装教程
  • UniApp 应用、页面与组件的生命周期详解
  • Java 版 spring cloud 工程系统管理 +二次开发 工程项目管理系统源码
  • axios使用笔记
  • 【五一创作】网络协议与攻击模拟-01-wireshark使用-捕获过滤器
  • 【学习笔记】「JOISC 2022 Day1」错误拼写
  • git 撤销add/commit,以及更换源命令
  • Unity VFX -- (4)创建burst粒子效果
  • 图片损坏修复软件,分享好用靠谱的软件
  • 基于海洋捕食者算法的极限学习机(ELM)回归预测-附代码
  • Microelectronic学习章节总结(2)-- data path和control unit设计
  • Java时间类(三) -- Calendar()(日历类)
  • 如何搭建一个HTTP实验环境
  • nrf52840系列(一):环境配置
  • Android InputChannel事件发送接收系统分析
  • 1.1 n阶行列式子的定义
  • 2023年度国家自然科学基金项目申请初审结果公布~
  • kubernetes项目部署
  • Qt之滑动条和进度条(QSlider、QProgressBar)
  • 国产ChatGPT命名图鉴
  • 【Android入门到项目实战-- 9.2】—— 传感器实战使用教程(靠近黑屏和计步器)
  • 【C++】STL标准库之vector