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

CD26.【C++ Dev】类和对象(17) static成员(下)

目录

1.练习题:带解法限制求1+2+3+...+n

题目

分析

Myclass设计

在Sum_Solution()在需要调用n次构造函数

方法1:变长数组

方法2:new对象

完整代码

提交结果

2.静态成员函数和非静态成员函数的互相调用问题

静态成员函数可以调用非静态成员函数吗?

非静态成员函数可以调用类的静态成员函数吗?

3.static函数的优势

当构造函数在类的private中类外调不了时,可以使用静态函数调用


1.练习题:带解法限制求1+2+3+...+n

题目

JZ64 求1+2+3+...+n

分析

读题发现题目对解法的限制比较严格:不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)

如果使用递归,则需要使用if来判断返回条件;如果使用位运算,返回的结果n*(n+1)>>1会用到乘号,也不行

本题可以使用CD25.【C++ Dev】类和对象(16) static成员(上)文章提到的静态成员变量来解决,让构造函数和静态成员变量打配合可以完美解决

Myclass设计

尝试初始化n个对象,显然会调用n次构造函数,以此来进行n次加法

 设计框架:

class Myclass
{
public:
    Myclass()
    {
        //操作
    }
private:
    //填写成员变量
};

n次加法应该遵循此顺序:+1、+2、+3、...、+n

需要用两个静态变量,一个存储累加的和(_ret),一个来控制每次相加的数字(_i)

则_ret初始化为0,_i初始化为1,执行一次构造函数时,_ret+=_i并且_i++

由于Myclass定义在Solution外,如果Sum_Solution()函数要取得_ret的值,在Myclass类中需要定义一个GetRet()函数来取得

class Myclass
{
public:
    Myclass()
    {
        _ret+=_i;
        _i++;
    }
    static int GetRet()//参数无this指针,可以使用Myclass::GetRet()来调用
    {
        return _ret;
    }
private:
    static int _i;
    static int _ret;
};
int Myclass:: _i=1;
int Myclass::_ret=0;

在Sum_Solution()在需要调用n次构造函数

如果使用while则会违背题意

int Sum_Solution(int n) 
{
    while(n--)//虽然可以通过,但是题目限定不能用while
    {
        Myclass obj; 
    }     
    return Myclass::GetRet();
}
方法1:变长数组
int Sum_Solution(int n) 
{
    Myclass obj[n];
    return Myclass::GetRet();
}
方法2:new对象
int Sum_Solution(int n) 
{
    new Myclass[n];//b不用接收返回值
    return Myclass::GetRet();
}

完整代码

class Myclass
{
public:
    Myclass()
    {
        _ret+=_i;
        _i++;
    }
    static int GetRet()
    {
        return _ret;
    }
private:
    static int _i;
    static int _ret;
};
int Myclass:: _i=1;
int Myclass::_ret=0;

class Solution 
{
public:
    int Sum_Solution(int n) 
    {
        Myclass obj[n]; //或者使用new对象       
        return Myclass::GetRet();
    }
};

提交结果

2.静态成员函数和非静态成员函数的互相调用问题

静态成员函数可以调用非静态成员函数吗?

答:之前在CD25.【C++ Dev】类和对象(16) static成员(上)文章中的特点6提到过:原本的静态成员函数的参数是没有隐藏this指针的,而调用非静态成员函数需要传this指针,因此不可以调用

如果要强行调用非静态成员函数其实也是可以的,不过要手动传指针,通过ptr->nonstaticfunction()来调用

#include <iostream>
using namespace std;
class Myclass
{
public:
    static void staticfunction(Myclass* ptr)
    {
        ptr->nonstaticfunction();
    }
    void nonstaticfunction()
    {
        cout << "void nonstaticfunction()" << endl;
    }
};

int main()
{
    Myclass obj;
    obj.staticfunction(&obj); 
    return 0;
}

运行结果:

非静态成员函数可以调用类的静态成员函数吗?

答:和第一问反过来,可以调用,例如以下代码:

#include <iostream>
using namespace std;
class Myclass2
{
public:
	static void staticfunction()
	{
		cout << "static void staticfunction()" << endl;
	}
};

class Myclass1
{
public:
	void nonstaticfunction()
	{
		Myclass2::staticfunction();
	}
};

int main()
{
	Myclass1 obj1;
	obj1.nonstaticfunction();
	return 0;
}

运行结果:

3.static函数的优势

当构造函数在类的private中类外调不了时,可以使用静态函数调用

例如在栈上创建对象:

#include <iostream>
using namespace std;
class Myclass
{
public:
    static Myclass Getobj()
    {
        Myclass obj;
        return obj;
    }
private:
    Myclass()
    {
        cout << "Myclass()" << endl;
    }
};

int main()
{
    Myclass ret = Myclass::Getobj();
    return 0;
}

注意:不能使用非静态成员函数! 非静态成员函数需要隐式传this指针,而有this指针的前提:this指针指向已经创建好的对象

运行结果:

例如在堆上创建对象:

#include <iostream>
using namespace std;
class Myclass
{
public:
    static Myclass* Getobj()
    {
        return new Myclass;
    }
private:
    Myclass()
    {
        cout << "Myclass()" << endl;
    }
};

int main()
{
    Myclass* ret = Myclass::Getobj();
    return 0;
}

*注:new会自动调用构造函数,这个特点后面文章再说,这里略过

运行结果:

相关文章:

  • c++进阶之----异常
  • java实体类常用参数验证
  • DepthAI ROS 安装与使用教程
  • 从传统 CLI 到自动化:网管协议( SNMP / NETCONF / RESTCONF)与 YANG
  • Java SE(2)——运算符
  • 艾尔登法环Steam不同账号存档互通方法与替换工具分享
  • nginx入门,部署静态资源,反向代理,负载均衡使用
  • 【基于LangChain的千问大模型工具调用】 Function CallingTool Calling简易示例
  • SCS翠鸟认证是什么,SCS翠鸟认证的意义?对企业发展好处
  • NO.88十六届蓝桥杯备战|动态规划-多重背包|摆花(C++)
  • SpringBoot 基础知识,HTTP 概述
  • 从递归入手一维动态规划
  • Java的内存模型
  • 高等数学同步测试卷 同济7版 试卷部分 上 做题记录 第二章导数与微分同步测试卷A卷
  • Java Lambda与方法引用:函数式编程的颠覆性实践
  • Soybean Admin 配置vite兼容低版本浏览器、安卓电视浏览器(飞视浏览器)
  • “pip“ is not recognized(pip无法被识别)
  • VBA即用型代码手册:书签Bookmarks
  • ARCGIS PRO 在已建工程地图中添加在线地图
  • Soybean Admin移除git-hooks永久关闭git校验