C++通过指针调用其他类的函数,void*指针强转为对象类型调用

1. 使用场景

类的实现中需要使用其他类的某个函数时,通常可以采用实例对象的方法,但是当两个类依赖很深,互相关联的时候的,这么操作往往不尽人意。

例如:类A中某函数用到类B的实例对象,而类B又需要A的某个函数,但是A和B都用到了一个全局变量,且A初始化用到了该变量。现在解决B需要A函数的问题。

如果B中创建A的对象实例,那么就会初始化改变全局变量的值,所以用这种方法会导致错误,我们不希望全局变量再次被初始化。

如下:
类A初始化了全局变量str,类A中创建了B的对象,B的对象修改了str。

此时B的useA()函数需要使用A的hello()函数,如果是直接用A的对象

void B::useA(){
	std::cout<<"B调用了A的函数:";
	//((A*)ptr)->hello();
	A tempA;
	tempA.hello();
}

那么输出结果为:
在这里插入图片描述
可以看到A重新初试化了str,而我们想要保留B修改str的结果,这种用法显然存在错误。


所以现在还有一种思路:==B通过一个强转的A类指针,来调用A中的函数==。

2. 测试代码

A.h

#ifndef A_H
#define A_H
#include<string>
using namespace std; 

class A
{
public:
	A();
	void hello();
	void createB();
	void changeStr();
};

#endif

A.cpp

#include "A.h"
#include "B.h"
#include<iostream>
extern string str;

A::A(){
	std::cout<<"创建了一个A对象\n\n";
	str="A初始化str";
	std::cout<<str<<"\n\n"; 
}

void A::createB(){
	std::cout<<"调用A的createB函数,创造一个B对象\n\n";
	B tempB;
	tempB.useA();
}

void A::hello(){
	std::cout<<"A的hello函数,现在str为:"<<str;
}


B.h

#ifndef B_H
#define B_H

class B
{
public:
	B();
	void useA(); 
	void *ptr;
};

#endif

B.cpp

#include "B.h"
#include "A.h"
#include<iostream>

extern string str;

B::B(){
	std::cout<<"B类的构造函数," ; 
	extern string str;
	str="B修改了str";
	std::cout<<str<<"\n\n"; 
}

void B::useA(){
	std::cout<<"B调用了A的函数:";
	((A*)ptr)->hello();
}码片

main.cpp

#include<iostream>
#include "a.h"
using namespace std;

string str;

int main(){
	A a;
	a.createB();
	return 0;
}

和刚才不同的是,这次把useA换成了
((A*)ptr)->hello();

首先在B中定义了一个void *ptr的空指针,然后强转成A* 去调用A的函数hello()

此时结果正确:
在这里插入图片描述

3.缺点

不过据我使用来看,这种方法也有一定的副作用,

例如运用到QT中去调用其他类的函数,只能调用一些和对象实例化关系不大的函数。如果函数中有必须创建对象的部分,比如QT中的视图必须绑定对象,那么该方法调用虽然可以通过编译,但是运行会产生崩溃。因为强转的空指针调用的时候没有指向的对象,编译器找不到运行时会crash,但是编译的时候是符合逻辑的。这可能会带来巨大的隐患。

4.改进

通过我的摸索,我觉得可以用全局变量的方法解决这种隐患,例如上述例子,在主函数中将A作为全局变量

A *a;

int main(){
	a=new A;	
	a->createB();
	return 0;
}

useA函数作如下修改

void B::useA(){
	std::cout<<"B调用了A的函数:";
	extern A *a;	
	a->hello();
}

结果依然正确
在这里插入图片描述

另外一个相关的QT编程问题,有兴趣可以看看我的另一篇博客,也是同样的方法:
https://blog.csdn.net/qq_51681065/article/details/128793426

各位网友,我的C++水平很低,这种方法只是分享。如果大家有其他想法,或者有开发经验的同志愿意分享这种问题的处理经验,非常欢迎!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西叶胡杨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值